您的位置:首页 > 其它

分布式事务处理两阶段提交实例

2017-04-17 16:04 323 查看

spring JTA多数据源事务管理详细教程

用框架的话只要配置好对个数据源,和工厂,公用一个JtaTransactionManager事物管理器,一个事物中有多个不同数据库操作不同数据源的时候会自动启用两阶段提交

,在加入事物标签的地方遇到任何异常就会自动回滚。

DataSourceTransactionManager是mybaits的事物管理器

HibernateTransactionManager是hibernate的事物管理器

JtaTransactionManager是分布式的事物管理器

这里的示例忘了在service加事物注解

刚好项目要用到多数据源,在网上查找了很多资料,花了几天的时间对spring、jta 、atomikos、hibernate进行多数据源事务管理的配置。
没有花时间弄maven,lib的地址:https://pan.baidu.com/s/1skdIC3N
也可以直接放在tomcat中运行,不过要用ws调用,因为没有做界面,ws入口在controller包里
下面是jta配置文件:

001
<
context:annotation-config
 
/>

002
    
<!-- 使用注解的包路径 -->
 
003
    
<
context:component-scan
 
base-package
=
"com.rongli.service,com.rongli.dao,com.rongli.controller"
 
/>

004
    
<!-- 支持  @Transactional 标记   -->

005
    
<
tx:annotation-driven
 
transaction-manager
=
"springJTATransactionManager"
 
proxy-target-class
=
"true"
/>

006
    
<!-- 导入cxf配置文件 -->

007
    
<
import
 
resource
=
"ws.cxf.xml"
/>

008
 
 
009
    
<!-- 加载properties配置文件 -->

010
    
<
bean
 
id
=
"propertyConfigurer"

011
        
class
=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
>

012
        
<
property
 
name
=
"locations"
>

013
            
<
list
>

014
                
<
value
>classpath:jta.jdbc.properties</
value
>

015
            
</
list
>

016
        
</
property
>

017
    
</
bean
>

018
    
 
019
    
<!--公有数据库连接池  -->

020
    
<
bean
 
id
=
"abstractXADataSource"
 
class
=
"com.atomikos.jdbc.AtomikosDataSourceBean"

021
        
init-method
=
"init"
 
destroy-method
=
"close"
 
abstract
=
"true"
>

022
        
<
property
 
name
=
"xaDataSourceClassName"

023
            
value
=
"com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"
 
/>

024
        
<
property
 
name
=
"poolSize"
 
value
=
"10"
 
/>

025
        
<
property
 
name
=
"minPoolSize"
 
value
=
"10"
 
/>

026
        
<
property
 
name
=
"maxPoolSize"
 
value
=
"30"
 
/>

027
        
<!--获取连接失败重新获等待最大时间,在这个时间内如果有可用连接,将返回-->

028
        
<
property
 
name
=
"borrowConnectionTimeout"
 
value
=
"60"
 
/>

029
        
<!--最大获取数据时间,如果不设置这个值,Atomikos使用默认的5分钟,

030
        
那么在处理大批量数据读取的时候,一旦超过5分钟,就会抛出类似 Resultset is close 的错误.-->

031
        
<
property
 
name
=
"reapTimeout"
 
value
=
"20000"
 
/>

032
        
<!-- 最大空闲时间 -->

033
        
<
property
 
name
=
"maxIdleTime"
 
value
=
"60"
 
/>

034
         
<!--连接回收时间-->

035
        
<
property
 
name
=
"maintenanceInterval"
 
value
=
"60"
 
/>

036
         
<!--java数据库连接池,最大可等待获取datasouce的时间-->

037
        
<
property
 
name
=
"loginTimeout"
 
value
=
"60"
 
/>

038
        
<
property
 
name
=
"testQuery"
>

039
            
<
value
>select 1</
value
>

040
        
</
property
>

041
    
</
bean
>

042
    
 
043
    
<!-- 客户数据库 -->

044
    
<
bean
 
id
=
"rlc_cus"
 
parent
=
"abstractXADataSource"
>

045
        
<
property
 
name
=
"uniqueResourceName"
 
value
=
"mysql/rlc_cus"
 
/>

046
        
<
property
 
name
=
"xaProperties"
>

047
            
<
props
>

048
                
<
prop
 
key
=
"URL"
>${jdbc.rlc_cus.properties}</
prop
>

049
                
<
prop
 
key
=
"user"
>${jdbc.rlc.user}</
prop
>

050
                
<
prop
 
key
=
"password"
>${jdbc.rlc.password}</
prop
>

051
                
<
prop
 
key
=
"pinGlobalTxToPhysicalConnection"
>true</
prop
>

052
            
</
props
>

053
        
</
property
>

054
    
</
bean
>

055
    
 
056
    
<!-- 系统数据库 -->

057
    
<
bean
 
id
=
"rlc_sys"
 
parent
=
"abstractXADataSource"
>

058
        
<
property
 
name
=
"uniqueResourceName"
 
value
=
"mysql/rlc_sys"
 
/>

059
        
<
property
 
name
=
"xaProperties"
>

060
            
<
props
>

061
                
<
prop
 
key
=
"URL"
>${jdbc.rlc_sys.properties}</
prop
>

062
                
<
prop
 
key
=
"user"
>${jdbc.rlc.user}</
prop
>

063
                
<
prop
 
key
=
"password"
>${jdbc.rlc.password}</
prop
>

064
                
<
prop
 
key
=
"pinGlobalTxToPhysicalConnection"
>true</
prop
>

065
            
</
props
>

066
        
</
property
>

067
    
</
bean
>

068
    
 
069
    
<!-- 公有SessionFactory配置 -->

070
    
<
bean
 
id
=
"baseSessionFactory"

071
        
class
=
"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"

072
        
abstract
=
"true"
>

073
        
<
property
 
name
=
"hibernateProperties"
>

074
            
<
props
>

075
                
<
prop
 
key
=
"hibernate.dialect"
>${hibernate.dialect}</
prop
>

076
                
<
prop
 
key
=
"hibernate.show_sql"
>${hibernate.format_sql}</
prop
>

077
                
<
prop
 
key
=
"hibernate.format_sql"
>${hibernate.show_sql}</
prop
>

078
                
<
prop
 
key
=
"javax.persistence.validation.mode"
>none</
prop
>

079
            
</
props
>

080
        
</
property
>

081
        
<!-- 自动扫描注解方式配置的hibernate类文件 -->

082
        
<
property
 
name
=
"packagesToScan"
 
value
=
"com.rongli.bean"
></
property
>

083
    
</
bean
>

084
    
 
085
    
<!-- sessionFactory配置-->

086
    
<!-- customer sessionFactory -->

087
    
<
bean
 
id
=
"cusSessionFactory"
 
parent
=
"baseSessionFactory"
>

088
        
<
property
 
name
=
"dataSource"
 
ref
=
"rlc_cus"
 
/>

089
    
</
bean
>

090
    
<!-- system sessionFactory -->

091
    
<
bean
 
id
=
"sysSessionFactory"
 
parent
=
"baseSessionFactory"
>

092
        
<
property
 
name
=
"dataSource"
 
ref
=
"rlc_sys"
 
/>

093
    
</
bean
>

094
 
095
    
<!-- atomikos事务管理器 -->

096
    
<
bean
 
id
=
"atomikosTransactionManager"

097
        
class
=
"com.atomikos.icatch.jta.UserTransactionManager"

098
        
init-method
=
"init"
 
destroy-method
=
"close"
>

099
        
<!-- 调用终止时,强制关闭 -->

100
        
<
property
 
name
=
"forceShutdown"
>

101
            
<
value
>true</
value
>

102
        
</
property
>

103
    
</
bean
>

104
    
<
bean
 
id
=
"atomikosUserTransaction"

105
        
class
=
"com.atomikos.icatch.jta.UserTransactionImp"
>

106
        
<
property
 
name
=
"transactionTimeout"
>

107
            
<
value
>2000</
value
>

108
        
</
property
>

109
    
</
bean
>

110
 
111
     
<!-- spring 事务管理器 -->

112
    
<
bean
 
id
=
"springJTATransactionManager"

113
        
class
=
"org.springframework.transaction.jta.JtaTransactionManager"
>

114
        
<
property
 
name
=
"transactionManager"
>

115
            
<
ref
 
bean
=
"atomikosTransactionManager"
 
/>

116
        
</
property
>

117
        
<
property
 
name
=
"userTransaction"
>

118
            
<
ref
 
bean
=
"atomikosUserTransaction"
 
/>

119
        
</
property
>

120
    
</
bean
>

121
    
 
122
    
<!-- 用于测试,发布到服务器上时删除 -->

123
    
<
bean
 
id
=
"systemServiceImpl"

124
        
class
=
"com.rongli.service.impl.SystemServiceImpl"
>

125
    
</
bean
>

 运行截图:
原2个数据库中都没有数据,图如下:



 



具体代码:






代码运行成功截图:


成功后数据库(乱码请忽略):






 
代码故意抛出异常:



代码运行失败:



失败后2个数据库中没有插入(事务回滚了):



 
 
参考: http://blog.csdn.net/super_scan/article/details/39400719  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐