HIS 架構修正GuideLine === [TOC] ##### Reference * [re-structure status](https://hackmd.io/ffUpYMhPQpCHqZbDhNDWDg) * [SecServer: application.grooy](https://hackmd.io/iAkfPaw7Soqh6gRXR7Ojzw) * [DBConn Usage](https://hackmd.io/LyFN8_ipTq6LdRZGDTfA5w) * [Runtime Issue](https://hackmd.io/dERAY9ZMRJaP67acERbuCQ) * [AIR Runtime Issue](https://hackmd.io/Z27TjZfPSRmG23waKN89_A) ## Pooling ### application.groovy * multi-dataSource ``` dataSources { dataSource { pooled = true logSql = true dbCreate = "none" // one of 'create', 'create-drop','update' url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver" driverClassName = "net.bull.javamelody.JdbcDriver" username = "emr" password = "chidapuser" } mrm { pooled = true logSql = true url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver" driverClassName = "net.bull.javamelody.JdbcDriver" username = "mrm" password = "chidapuser" } query { pooled = true logSql = true url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver" driverClassName = "net.bull.javamelody.JdbcDriver" username = "reportquery" password = "chidapuser" } } ``` ### Javamelody Spring DataSource * 設置default dataSource {...}, environment不需要pooled, jmxExport, jmxEnabled行為 ``` dataSource { jmxExport = true pooled = true dbCreate = "none" // one of 'create', 'create-drop','update' dialect = "org.hibernate.dialect.OracleDialect" url = "" username = "" password = "" properties { jmxEnabled = true } } ``` ![](https://i.imgur.com/soLESOp.png) ### getBean() * 取用'dataSource' bean * 取用'dataSourceUnproxied' bean 會產生另一個db session(不再同一個Transaction Scope) ``` DataSource ds = Holders.getGrailsApplication().getMainContext().getBean("dataSource") ``` 在getConnection的時候優先以傳入參數取bean,傳入參數取不到,再以dataSource_xxxx的模式取,如果此處也取不到bean,會拋出例外。 ### closeConnection, autoCommit * 不需closeConnection(tx manager會介入), 禁止操作autoCommit等行為, 一律由dataSource設定控制 * BatchTool.closeConnection會檢查dataSource型別,屬於TransactionAwareDataSourceProxy的,不做close ## Transaction Management ### @Transactional * Service Endpoint(標註@RemotingDestination/@GrailsCxfEndpoint)必須與Service Bean分離撰寫 * 所有*Service Bean class 都需標註(@Transactional) * 確定cross service class, method皆能control error rollback * 確定cross 'gorm', getBean(dataSource), getBean(dataSource_XXX)皆能control error rollback * his服務使用Cxf提供SOAP服務,確認所有標註GrailsCxfEndpoint的service class都必須分離撰寫,以sec為例,只有下圖黃色框起來的class提供對外服務: ![](https://i.imgur.com/E0Gjsno.png) ### RuntimeException * Tx Rollback只有checkedException awared. * 檢視try catch是否正確throw RuntimeException * 以下圖為例,在catch例外之後,throw出去讓hibernete察覺例外 ![](https://i.imgur.com/BS9Lal5.png) ## JavaMelody ### Spring dataSource reference ``` url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver" driverClassName = "net.bull.javamelody.JdbcDriver" ``` ## Coding Pattern ### 取號from getConnection() 透過Sequence.nextval, 禁止```max(id)+1``` ``` sql select EmrTeachingFrequent_Seq_Id.nextval id from dual ``` ## Error Log ### filebeat.yaml ``` filebeat.inputs: ... multiline.type: pattern multiline.pattern: '^[[:space:]]+(at|\.{3})[[:space:]]+\b|^Caused by:' multiline.negate: false multiline.match: after ``` ``` [tsengeagle@TP-HISHA1-APL03 ~]$ cat /etc/filebeat/inputs.d/EventServer1_input.yml - type: log paths: - /home/tomcat/server/EventServer/logs/catalina.out fields: service_name: EventServer1 server_name: EventServer log_type: process tags: ["EventServer","EventServer1","process"] multiline.pattern: '^[[:space:]]|^#|^[[:space:]]+(at|\.{3})\b|^Caused by:' multiline.negate: false multiline.match: after ``` ## Hibernate Reference https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#flushing