您的位置:首页 > 编程语言 > Java开发

【Spring】spring-mvc hibernate druid jdbc等数据源事务配置详解(解决注解事务不生效问题)

2016-04-12 17:10 1106 查看
今天把工程事务不生效的事情个解决了。所有的配置都是正常的,就是不知道为什么事务不生效。

工程架构为spring-mvc + spring + druid 

首先说下spring的事务:

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。 

    DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager

具体如下图:



由上面知道无论切换哪种数据源都有对应的Datasource和TransactionManager与之对应

例如我的druid:

<!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
<bean id="dsMaster" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />

<!-- 基本属性 url、user、password 127.0.0.1 -->
<property name="url" value="${jdbc.mysql.url}" />
<property name="username" value="${jdbc.mysql.username}" />
<property name="password" value="${jdbc.mysql.password}" />

<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="3" />
<property name="minIdle" value="3" />
<property name="maxActive" value="20" />

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />

<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用) <property name="poolPreparedStatements"
value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize"
value="20" /> -->

<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>

<!-- <bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dsMaster"></property>
</bean> -->
<bean id="transactionManager"
class="com.znwx.server.db.MyTranstion">
<property name="dataSource" ref="dsMaster"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<!-- jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dsMaster" />
</property>
</bean>

MyTranstion继承了spring的DataSourceTransactionManager,只是为了调试。。

再加上一个:

<context:annotation-config/>
让注解生效。
在方法或者类上增加@Transactional("transactionManager")即可,名称是为了如果有多数据源好区分,一个数据源可以不用名称,它都带了什么参数自行百度吧很多的。

我这里用注解实现的,还有另外4种,比较常用的是aop拦截的。自行百度
贴上aop的:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="merge*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="put*" propagation="REQUIRED" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="count*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="list*" propagation="SUPPORTS" read-only="true" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.znwx.server..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>

重要点:注解失效的问题解决
由于用了spring-mvc所以在spring-mvc.xml中也用了自动扫描注解的标签:

<context:component-scan
base-package="com.znwx.*"/>

这个就要注意了,这里扫描了所有的包,就会和事务的冲突了,所以这里应该改为只扫描controller层的包,service层和dao层只扫描当前层,否则事务将不生效。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 事务 java