Spring 事物异常[Transaction rolled back because it has been marked as rollback-only]
spring通过TransactionInterceptor和AbstractPlatformTransactionManager的实现类控制数据库事务。
创建数据库
Animal表
create table Animal(name nvarchar(20))
create table Person(name nvarchar(20))
<import resource="applicationContext-common.xml"/><import resource="applicationContext-service.xml"/>
<bean id="baseService" abstract="true"><property name="dataSource" ref="dataSource"/></bean><bean id="animalService" parent="baseService"/><bean id="personService" parent="baseService"/><bean id="allService" parent="baseService"><property name="animalService" ref="animalService"/><property name="personService" ref="personService"/></bean>
<!-- 配置属性配置文件 --><bean id="propertyConfigurer" destroy-method="close"> <property name="driverClassName" value="${jdbc.database.driverClassName}"/> <property name="url" value="${jdbc.database.url}"/> <property name="username" value="${jdbc.database.username}"/> <property name="password" value="${jdbc.database.password}"/> </bean> <!-- 配置事务管理器 --><bean id="transactionManager"ref="dataSource" /></bean><!-- 具体事务配置 --><aop:config><aop:pointcut expression="execution(* service.*.*(..))"id="allManagerMethods" /><aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethods" /></aop:config><!-- 事务传播特性的配置 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="*" propagation="REQUIRED" /></tx:attributes></tx:advice>jdbc.database.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.database.url=jdbc:oracle:thin:@127.0.0.1:1521:oraclejdbc.database.username=scottjdbc.database.password=tiger
public interface AllService {public void addAll(String personName,String animalName) throws Exception;}public class AllServiceImpl extends JdbcDaoSupport implements AllService {private PersonService personService;private AnimalService animalService;@Overridepublic void addAll(String personName, String animalName) throws Exception {try{personService.addPerson(personName);}catch (Exception e) {System.out.println(e.toString());}animalService.addAnimal(animalName);}public void setPersonService(PersonService personService) {this.personService = personService;}public void setAnimalService(AnimalService animalService) {this.animalService = animalService;}}public interface AnimalService {public void addAnimal(String animalName) throws Exception;}public class AnimalServiceImpl extends JdbcDaoSupport implements AnimalService{@Overridepublic void addAnimal(String animalName) throws Exception {this.getJdbcTemplate().update("insert into ANIMAL values(?)",new Object[]{animalName});}}public interface PersonService {public void addPerson(String personName)throws Exception;}public class PersonServiceImpl extends JdbcDaoSupport implements PersonService {@Overridepublic void addPerson(String personName) throws Exception {this.getJdbcTemplate().update("insert into PERSON values(?)",new Object[]{personName});}}public class SpringTest {private static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");public static void main(String[] args) throws Exception{AllService allService=(AllService) applicationContext.getBean("allService");String personName="will";String animalName="小狗";allService.addAll(personName,animalName);}}org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into PERSON values(?)]; SQL state [72000]; error code [12899]; ORA-12899: 列 "SCOTT"."PERSON"."NAME" 的值太大 (实际值: 32, 最大值: 20); nested exception is java.sql.SQLException: ORA-12899: 列 "SCOTT"."PERSON"."NAME" 的值太大 (实际值: 32, 最大值: 20)Exception in thread "main" org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-onlyat org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:695)at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)at $Proxy2.addAll(Unknown Source)at test.SpringTest.main(SpringTest.java:16)