接着前面两篇文章:
spring的内嵌事务必须在jdbc template以及org.springframework.jdbc.datasource.DataSourceTransactionManager下才支持 :
所以配置xml:
<!-- 用aspectJ的代理方式 -->
<aop:aspectj-autoproxy/>
<context:annotation-config />
<context:component-scan base-package="my.aop.dao" />
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
<property name="nestedTransactionAllowed" value="true"></property>
</bean>
<bean id="departmentDao" class="my.aop.dao.DepartmentDaoJdbcImpl" scope="prototype">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="userDao" class="my.aop.dao.UserDaoJdbcImpl" scope="singleton">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="myService" class="my.aop.dao.MyService">
<property name="departmentDao">
<ref bean="departmentDao" />
</property>
<property name="userDao">
<ref bean="userDao" />
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!-- org.apache.commons.dbcp.BasicDataSource class=" -->
<property name="url" value="jdbc:oracle:thin:@10.80.1.171:1521:CBS3001"></property>
<property name="maxActive" value="3"></property>
<property name="username" value="cone3590_dev"></property>
<property name="password" value="arbor123"></property>
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="defaultAutoCommit">
<value>false</value>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
2。 UserDaoJdbcImpl 类:
public class UserDaoJdbcImpl extends JdbcDaoSupport implements UserDao {
public Session saveUser(User user, Session s) {
// TODO Auto-generated method stub
return null;
}
//当saveUser的注解为propagation = Propagation.REQUIRED时v$transaction有一条数据,
v$lock_object有两个表被锁
v$lock有三条数据(一条departments的,两条users的)
当saveUser的注解为propagation = Propagation.REQUIRES_NEW时v$transaction有两条数据,
v$lock_object有两个表被锁
v$lock有四条数据(两条departments的,两条users的)
注意:与template的datasouece的hashcode好像没关系
@Transactional(readOnly = false, propagation = Propagation.NESTED)
public void saveUser(User user) {
this.getJdbcTemplate().execute("update users set first_name='"+user.getName().getFirstName()+"' where id="+user.getId()+" ");
try {
//注意用红色方式得到连接是新的连接,千万注意,必须用黑体加粗方式
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.getDataSource());
Connection conn=conHolder.getConnection();
// Connection s=getJdbcTemplate().getDataSource().getConnection();
System.out.println(" in MyService: saveUser get tran is clise:"+s.isClosed()+"is commited:");
//System.out.println(" in MyService: departmentDao get tran wasCommitted:"+s.getTransaction().wasCommitted());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
3.DepartmentDaoJdbcImpl 类
public class DepartmentDaoJdbcImpl extends JdbcDaoSupport implements
DepartmentDao {
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public Session saveDepartment(Department user, User u, UserDao userDao) {
this.getJdbcTemplate().execute("update departments set name='"+user.getName()+"' where id="+user.getId()+"");
try {
//注意用红色方式得到连接是新的连接,千万注意,必须用黑体加粗方式
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.getDataSource());
Connection conn=conHolder.getConnection();
// Connection s=getJdbcTemplate().getDataSource().getConnection();
Savepoint sp=null;
try {
System.out.println("Connection.getMetaData().supportsSavepoints() "+conn.getMetaData().supportsSavepoints());
System.out.println("departments conn hashcode="+conn.hashCode()+"departments conn is closed:"+conn.isClosed());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// System.out.print(conn.getMetaData());
sp=conn.setSavepoint();
userDao.saveUser(u);
} catch (Exception e) {
try {
conn.rollback(sp);//回滚到保存点
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return null;
}
4.测试类MyService。java
public void saveDepartAndEmpJDbc(){
Department dep=new Department();
dep.setId(1);
dep.setName("test jdbc savepoint");
User u=new User();
u.setId(1);
Name n=new Name();
n.setFirstName( new Date() +
"222222222" +
"2222" +new Date());
u.setName(n);
u.setAccount(1);
departmentDao.saveDepartment(dep,u,userDao); //saveDepartment嵌套调用了 userDao.saveUser(u);
//userDao.saveUser(u);
System.out.println(" return ");
}