在项目中遇到了分布式服务的情况,这个时候就需要配置多个数据源,一个是oracle,一个sqlserver。
早就知道hibernate中有分布式事务的功能支持-----jta事务。
自己就翻阅书籍,上网查资料学习了一下。了解了一下jdbc事务和jta事务的区别。
自己总结如下:
1.jdbc事务,开启事务的时候就获取数据库连接,关闭事务的时候放掉数据库连接,并放回数据库连接池。
2.jta事务,开启事务的时候不会获取数据库连接,而是当你执行第一个sql的时候才去获取数据库连接,执行完之后就放掉连接。
对比:jta事务更加高效,缩短了占用数据库连接的时间。
如果配置的jta事务,那么数据源是在tomcat或者weblogic等服务器中配置的,这里就用到了jndi的知识,启动的时候会生成jndi树,把数据库与jndi绑定,通过jndi来访问数据库连接。如ssh+tomcat的话配置如下:
修改Tomcat_Home/conf/server.xml,在GlobalNamingResources中加入:
Xml代码
1. <Resource name="jdbc/DataSource" auth="Container"
2. type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
3. url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"
4. username="user" password="password" maxActive="20" maxIdle="10"
5. maxWait="-1"/>
<Resource name="jdbc/DataSource" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"
username="user" password="password" maxActive="20" maxIdle="10"
maxWait="-1"/>
再在Context中加入引用:
Xml代码
1. <ResourceLink name="jdbc/DataSource" global="jdbc/DataSource" type="javax.sql.DataSource"/>
<ResourceLink name="jdbc/DataSource" global="jdbc/DataSource" type="javax.sql.DataSource"/>
如果不加,则在使用的时候会出现:Cannot create JDBC driver of class '' for connect URL 'null' 错误
在web.xml定义:
Xml代码
1. <resource-ref>
2. <description>popuserDataSource</description>
3. <res-ref-name>jdbc/DataSource</res-ref-name>
4. <res-type>javax.sql.DataSource</res-type>
5. <res-auth>Container</res-auth>
6. </resource-ref>
<resource-ref>
<description>popuserDataSource</description>
<res-ref-name>jdbc/DataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
在Spring中引用:
Xml代码
1. <bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
2. <property name="jndiName" value="java:comp/env/jdbc/DataSource"/>
3. <property name="expectedType" value="javax.sql.DataSource"/>
4. </bean>
<bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/DataSource"/>
<property name="expectedType" value="javax.sql.DataSource"/>
</bean>
完成,这样数据源就就位了,至于hibernate对jta的配置网上有很多资料。
传统的jdbc事务,不可以开启一个事务,接着再开启,也就是不能同时开启两个事务,可以先开启一个,commit之后,再开启一个,commit之后,再开启一个。。。。
其他的一点知识:
一般sessionFactory.openSession();
session.get();
session.close();
session.get();方法首先为session分陪一个数据库连接,然后调用setAutoCommit(false);把它变为手工提交模式,实现隐士的开启一个jdbc事务。
那么session。close()方法都执行了那些呢?
先调用session占用的连接的对象的close方法,关闭数据库连接,返回连接池。至于关闭之后提没提交事务,这个取决于第三方对java。sql。connection的close方法的实现,oracle是默认提交的,有一些是默认撤销事务的。