关于spring的事务管理(单数据库):纯属猜测。
2010-12-10 12:39
681 查看
事务不应该由dao管理,而应该由service管理
最重要的是如下四个类
DataSource :数据库的Connection连接工厂
DataSourceUtils:
参与同一个事务的多个dao实际上应该是共享同一个conn的。
DataSourceUtils.getConnection(dataSource)取得当前ThreadLocal的conn,如果没有从dataSource创建一个。
DataSourceUtils.releaseConnection(conn, dataSource)未必真正关闭连接。
DataSourceTransactionManager
TransactionProxyFactoryBean;拦截具体业务对象方法调用,中间根据DataSourceTransactionManager设置进行事务管理
文笔不行,说不明白,举个例子:
dao1{
method(){
conn= DataSourceUtils.getConnection(dataSource);
...........
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
dao2{
method(){
conn= DataSourceUtils.getConnection(dataSource);
...........
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
service{ method(); }
serviceImp{
method(){
dao1.method();
dao2.method();
}
}
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="service"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="serviceImp" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
分析:
当调用service.method()时,开始TransactionProxyFactoryBean拦截此方法指定当前线程需要事务,然后调用dao1.method(),
调用conn= DataSourceUtils.getConnection(dataSource)
判断当前线程还没有conn则创建一个,因为此时线程需要事务所以conn.setAutoCommit(false),执行数据库作,
然后DataSourceUtils.releaseConnection(conn, dataSource),判断当前线程需要事务所以不真正关闭连接继续,dao1.method()返回。
调用dao2.method(),调用conn= DataSourceUtils.getConnection(dataSource)判断当前线程有一个conn就返回这个conn,(此时dao1.method()和dao2.method()已经共用了这个conn),执行数据库操作,然后DataSourceUtils.releaseConnection(conn, dataSource),判断当前线程需要事务
所以不真正关闭连接继续,dao2.method()返回。service.method()返回,TransactionProxyFactoryBean拦截取得当前线程连接提交事务,关闭清除连接。这样两个dao就参与到了一个事务当中。如果service.method()抛出异常,则TransactionProxyFactoryBean在service.method()返回时拦截取得当前线程连接回滚事务,关闭清除连接。
不知道猜得对不对
最重要的是如下四个类
DataSource :数据库的Connection连接工厂
DataSourceUtils:
参与同一个事务的多个dao实际上应该是共享同一个conn的。
DataSourceUtils.getConnection(dataSource)取得当前ThreadLocal的conn,如果没有从dataSource创建一个。
DataSourceUtils.releaseConnection(conn, dataSource)未必真正关闭连接。
DataSourceTransactionManager
TransactionProxyFactoryBean;拦截具体业务对象方法调用,中间根据DataSourceTransactionManager设置进行事务管理
文笔不行,说不明白,举个例子:
dao1{
method(){
conn= DataSourceUtils.getConnection(dataSource);
...........
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
dao2{
method(){
conn= DataSourceUtils.getConnection(dataSource);
...........
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
service{ method(); }
serviceImp{
method(){
dao1.method();
dao2.method();
}
}
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="service"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="serviceImp" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
分析:
当调用service.method()时,开始TransactionProxyFactoryBean拦截此方法指定当前线程需要事务,然后调用dao1.method(),
调用conn= DataSourceUtils.getConnection(dataSource)
判断当前线程还没有conn则创建一个,因为此时线程需要事务所以conn.setAutoCommit(false),执行数据库作,
然后DataSourceUtils.releaseConnection(conn, dataSource),判断当前线程需要事务所以不真正关闭连接继续,dao1.method()返回。
调用dao2.method(),调用conn= DataSourceUtils.getConnection(dataSource)判断当前线程有一个conn就返回这个conn,(此时dao1.method()和dao2.method()已经共用了这个conn),执行数据库操作,然后DataSourceUtils.releaseConnection(conn, dataSource),判断当前线程需要事务
所以不真正关闭连接继续,dao2.method()返回。service.method()返回,TransactionProxyFactoryBean拦截取得当前线程连接提交事务,关闭清除连接。这样两个dao就参与到了一个事务当中。如果service.method()抛出异常,则TransactionProxyFactoryBean在service.method()返回时拦截取得当前线程连接回滚事务,关闭清除连接。
不知道猜得对不对
相关文章推荐
- 关于spring+mybatis操作数据库多次异常 事务不被spring管理问题
- Spring学习(4):Spring数据库事务管理
- spring中常用管理数据库事务的管理器
- 关于Spring事务管理中@Transactional的参数配置
- 关于spring 与Hibernate 结合使用的事务管理
- 关于Spring事务管理无法回滚的问题
- Spring3数据库事务管理机制
- 关于spring事务管理
- spring 事务管理 1(使用spring的JdbcTemplate访问数据库)
- 关于spring 的事务管理
- mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚
- 关于spring3.0 后的 事务注解管理指定数据源问题
- 关于spring声明式事务管理异常处理的测试和小结
- Spring之旅、装配Bean、最小化Spring XML配置、面向切面的Spring、征服数据库、事务管理示例源代码
- Spring.Net实现跨数据库服务层事务管理
- 关于Spring管理的事务如何配置回滚及try catch情况下的回滚
- Spring的事务管理和数据库事务相关知识
- Spring的数据库操作和事务管理
- 关于spring管理事务的学习总结。
- Spring3数据库事务管理机制