spring hibernate transaction

spring hibernate transaction 简单实例


版本:

spring 3.2.1

hibernate 4.0.1


程序目录:



IStartService

package com.unei.service;

public interface IStartService {
	public void addPerson();
}

StartService

package com.unei.service.impl;

import javax.annotation.Resource;

import com.unei.dao.IPersonDao;
import com.unei.model.Person;
import com.unei.service.IStartService;

public class StartService implements IStartService {

	@Resource
	IPersonDao personDao;

	@Override
	public void addPerson() {
		Person person = new Person();
		person.setName("sunlei");
		person.setVersion(1);
		personDao.add(person);
		
		person.setName("sdfsdf");
		personDao.add(person);
		throw new RuntimeException("asdfsafd");
	}

}

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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    ">

	<!--  <aop:aspectj-autoproxy proxy-target-class="true"/>-->

	<!-- 注册PostProcessor - 负责扫描使用了 JSR-250 注释的 Bean,并对它们进行相应的操作 -->
	<bean
		class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
	<context:component-scan base-package="com.unei">
		<context:include-filter type="regex"
			expression="com.unei.service.*" />
	</context:component-scan>

	<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="org.mariadb.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/tx" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
	</bean>

	<bean id="mySessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="configLocation" value="classpath:hibernate.cfg.xml" />
		<property name="dataSource" ref="myDataSource" />
		<property name="hibernateProperties">
			<value>
				hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
			</value>
		</property>
	</bean>
	
	<!-- 配置事务管理器 -->
	<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="mySessionFactory"/>
	</bean>
	
	<!-- 配置事务传播特性 -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	<!-- aop 配置-->
	<aop:config >
		<aop:pointcut id="startServiceMethods" expression="execution(* com.unei.service.*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="startServiceMethods"/>
	</aop:config>
	
	<bean id="ss" class="com.unei.service.impl.StartService"/>
</beans>

测试:

package com.unei.service.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.unei.service.IStartService;


public class app {

	/**
	 * @param args
	 */
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ApplicationContext context=new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
		IStartService ss=(IStartService)context.getBean("ss");
		ss.addPerson();
	}

}
程序异常,事务未提交,所以数据未写入数据库。


Spring事务传播特性:

  • PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。
  • PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,则抛出异常。
  • PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NERVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则与PROPAGATION_REQUIRED操作类似。

嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别 :
    它们非常类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务管理器的支持。
    使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTED时,需要JDBC 3.0以上驱动及1.4以上的JDK版本支持。其它的JTA TrasactionManager实现可能有不同的支持方式。

你可能感兴趣的:(spring,Hibernate,事务,transaction)