[問題] 請問 Spring transaction 設定

作者: jtorngl (Pedrosa go!)   2017-01-30 17:04:45
最近想搞懂 Spring 怎麼管理 transaction 的
先從程式可以開始跑開始,照書上設定了幾個範例
目前在試 @Transactional,遇到無法 rollback 的問題,想請教
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd ">
<context:property-placeholder location="classpath:idv/sql/jdbc.properties" />
<context:component-scan base-package="idv.spring.tx.dao,
idv.spring.tx.ch02_spring.e_annotation.service" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
</beans>
Service.java
@Service("spring_annotation_memberService")
public class MemberService {
@Autowired
@Qualifier("jdbc_tx_memberDao")
private MemberDao memberDao;
@Autowired
@Qualifier("jdbc_tx_memberDetailDao")
private MemberDetailDao memberDetailDao;
@Transactional(propagation = Propagation.REQUIRED, rollbackFor =
Exception.class)
public void saveMember(Member member, MemberDetail memberDetail) {
try {
memberDao.addMember(member);
memberDetailDao.addMemberDetail(memberDetail);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Main.java
public class SpringTxMain {
public static void main(String[] args) {
ApplicationContext context =
new
ClassPathXmlApplicationContext("classpath:idv/spring/tx/ch02_spring/e_annotation/applicationContext.xml");
Member member = new Member();
member.setId("xxxxx");
member.setAccount("xxxxx");
member.setNickName("Xxxxx");
member.setStatus(Status.ACTIVE);
MemberDetail memberDetail = new MemberDetail();
memberDetail.setId("00001");
// memberDetail.setMemberId(member.getId());
memberDetail.setMemberId(member.getId() + "xxxxxxxxxxxxxxxx"); //
this would cause SQLException
memberDetail.setFirstName("YYYY");
memberDetail.setLastName("ZZZZ");
memberDetail.setIdNum("asdfghjkl");
MemberService memberService =
context.getBean("spring_annotation_memberService", MemberService.class);
memberService.saveMember(member, memberDetail);
((AbstractApplicationContext) context).close();
}
}
Dao 的部份應該不用附程式吧,就是直接用 jdbcTemplate 而已
故意在 service 的 memberDetailDao.addMemberDetail(memberDetail); 出錯
不過 memberDao.addMember(member); 還是成功寫入資料庫了
測試的 DB 是 H2 和 MySQL(community-5.7.14.0)
一開始在練習由程式控制 transaction 時
有遇到 org.springframework.jdbc.datasource.DriverManagerDataSource
不能 disable auto-commit,所以一直失敗
改為 org.apache.commons.dbcp.BasicDataSource
並設定 <property name="defaultAutoCommit" value="false" /> 就成功
不過接著試了
1. DataSourceTransactionManager
2. TransactionTemplate
都是只用 org.springframework.jdbc.datasource.DriverManagerDataSource
也有成功 rollback
再試
3. TransactionProxyFactoryBean
4. <tx:advice>
也是失敗
其中 TransactionProxyFactoryBean 管理 transaction 設定比較複雜
所以先跳過不看
<tx:advice> 則應該是 <aop:pointcut> 的部份設定有錯
這要回頭去補 AOP 的設定方式,也是後續把 AOP 設定搞懂後再說
現在是試 @Transactional 的方式時也失敗了,但是找不到錯在哪
想請教先進問題在哪?
另外想請教想知道 Spring 怎麼實做的
比如 AOP,大概只知道 proxy pattern
但想知道諸如 @Aspect,@Before,<aop:config>...
如何爬原始碼會比較好
作者: ssccg (23)   2017-01-31 03:03:00
rollbackFor = Exception.class,但是你把例外全catch了?

Links booklink

Contact Us: admin [ a t ] ucptt.com