在spring项目中,使用jfinal的db功能,不知道怎样配置才能使事物正常
@JFinal 你好,想跟你请教个问题:
目前是老项目,spring mvc+hibernate编写的,现在想不影响老项目的情况下,把jFinal的DB功能加进去,以前的代码还是hibernate,新功能就使用jFinal的db
目前的的配置如下:
<bean id="dataSource" name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 这一项可配可不配,如果不配置druid会根据url自动识别dbType, 然后选择相应的driverClassName --> <property name="driverClassName" value="${jdbc.driverClassName}" /> <!-- 配置这个属性的意义在于,如果存在多个数据源,监控的时候 可以通过名字来区分开来。如果没有配置,将会生成一个名字, 格式是:"DataSource-" + System.identityHashCode(this) --> <property name="name" value="DataSource-autolink" /> <!-- 连接数据库的url --> <property name="url" value="${jdbc.url}" /> <!-- 连接数据库的用户名 --> <property name="username" value="${jdbc.username}" /> <!-- 连接数据库的密码。如果你不希望密码直接写在配置文件中, 可以使用ConfigFilter --> <property name="password" value="${jdbc.password}" /> <!-- 初始化时建立物理连接的个数。初始化发生在显示调用init方法, 或者第一次getConnection时 --> <property name="initialSize" value="1" /> <!-- 连接池最大连接数量 --> <property name="maxActive" value="20" /> <!-- 连接池最小连接数量 --> <property name="minIdle" value="1" /> <!-- 获取连接时最大等待时间,单位毫秒。配置了maxWait之后, 缺省启用公平锁,并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁 --> <property name="maxWait" value="60000" /> <!-- 是否缓存preparedStatement,也就是PSCache。 PSCache对支持游标的数据库性能提升巨大,比如说oracle。 在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。 5.5及以上版本有PSCache,建议开启 --> <property name="poolPreparedStatements" value="true" /> <!-- 要启用PSCache,必须配置大于0,当大于0时, poolPreparedStatements自动触发修改为true。 在Druid中,不会存在Oracle下PSCache占用内存过多的问题, 可以把这个数值配置大一些,比如说100 --> <property name="maxOpenPreparedStatements" value="100" /> <!-- 用来检测连接是否有效的sql,要求是一个查询语句。 如果validationQuery为null,testOnBorrow、testOnReturn、 testWhileIdle都不会其作用。在mysql中通常为select 'x',在oracle中通常为 select 1 from dual --> <property name="validationQuery" value="${hibernate.validationQuery}" /> <!-- 物理连接初始化的时候执行的sql --> <property name="connectionInitSqls" value="${hibernate.validationQuery}" /> <!-- 申请连接时执行validationQuery检测连接是否有效, 做了这个配置会降低性能 --> <property name="testOnBorrow" value="false" /> <!-- 归还连接时执行validationQuery检测连接是否有效, 做了这个配置会降低性能 --> <property name="testOnReturn" value="false" /> <!-- 建议配置为true,不影响性能,并且保证安全性。 申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis, 执行validationQuery检测连接是否有效 --> <property name="testWhileIdle" value="true" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <!-- 有两个含义: 1) Destroy线程会检测连接的间隔时间 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <!-- Destory线程中如果检测到当前连接的最后活跃时间和当前时间的差值大于 minEvictableIdleTimeMillis,则关闭当前连接 --> <property name="minEvictableIdleTimeMillis" value="300000" /> <!-- 是否打开removeAbandoned功能,对于建立时间超过removeAbandonedTimeout的连接强制关闭 --> <property name="removeAbandoned" value="false" /> <!-- 多少秒删除连接,秒为单位,指定连接建立多长时间就需要被强制关闭,如果removeAbandoned为false,这个设置项不再起作用 --> <property name="removeAbandonedTimeout" value="28800" /> <!-- 关闭abanded连接时输出错误日志,指定发生removeAbandoned的时候,是否记录当前线程的堆栈信息到日志中 --> <property name="logAbandoned" value="true" /> <!-- 属性类型是字符串,通过别名的方式配置扩展插件, 常用的插件有: 监控统计用的stat 日志用的log4j 防御sql注入的wall --> <!-- 保存DruidDataSource的监控记录,DruidDataSource会定期把监控数据输出到日志中 --> <property name="timeBetweenLogStatsMillis" value="300000" /> </bean> <!-- spring 事务管理 ,ActiveRecordPlugin可以获得此 dataSource 可以把事务交给spring 管理 --> <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <property name="targetDataSource" ref="dataSource" /> </bean> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSourceProxy"></property> </bean> <!-- 拦截器方式配置事物 --> <tx:advice id="transactionAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!-- 把事务控制在Service层 --> <aop:config> <aop:pointcut id="transactionPointcut" expression="execution(* other.**.service..*Impl.*(..)))" /> <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" /> </aop:config>
<bean id="activeRecordConfig" class="other.ActiveRecordConfig"></bean>
package other; import javax.annotation.Resource; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; public class ActiveRecordConfig { @Resource(name = "dataSource") private DataSource dataSource; @Bean(initMethod = "start", destroyMethod = "stop") public ActiveRecordPlugin init() { ActiveRecordPlugin arp = new ActiveRecordPlugin(dataSource); return arp; } }
package jfinal.test; import com.jfinal.aop.Before; import com.jfinal.plugin.activerecord.Db; import com.jfinal.plugin.activerecord.tx.Tx; public class TestServiceImpl implements TestServiceI { @Override public void save() { Db.update("insert into a set id = '2'"); Db.update("insert into b set id = '1'"); } }
波总有没有这方面的解决方案?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果TestService 是无状态的,可以在controller 中加上 static 关键字,可以避免每次new出对象,另外 MyTxByRegexMethod 这样的功能jfinal已经提供了,直接使用一下:com.jfinal.plugin.activerecord.tx.TxByMethodRegex 即可,使用的时候可以临时传入正则,提升灵活性
临时传入正则这样用: Duang.duang(target, new TxByMethodRegex("(.*update.*|.*save.*)");
@JFinal
我用这种方式解决了,但是代码可能不够优雅。
先自己定义一个MyTxByMethodRegex
service不用做改动,也不需要写@Before(Tx.class)
controller可以写
下面调用的时候,如果不是save/update/delete这种,就不会开启事物。
如果是用@Before(Tx.class) 为特定的方法加事务,不会影响到其它方法,如果是inject interceptor的方式,可以使用 Duang.duang(target, new TxByRegex("(.*update.*|.*save.*)") 这样来做
其实可以写个spring Aop,然后把tx里面的代码copy过去就ok了,这样比较优雅!
代码见: http://git.oschina.net/596392912/codes
查看:JFinalTxAop.java 和 JFinalTx.java,这样之后就能按照spring的习惯来了。
@JFinal 帮我顶一下