1、@Transactional使用位置
Ⅱ 写在接口方法上,该接口的所有实现类的该方法都会有事务;
Ⅰ 写在实现类上,该类中的所有方法都会有事务;
Ⅱ 写在实现类方法上,该方法上有事务。
建议:写在实现类或实现类的方法上。
2、PlatformTransactionManager
PlatformTransactionManager是Spring中的事务管理接口,具体如下:
3、DataSourceTransactionManager
Spring中JDBC事务管理实现类是DataSourceTransactionManager,所以我们使用MyBatis时,如果需要进行事务管理则配置该事务管理即可。
1、基础准备
jdbc.properties如下:
JdbcConfig如下:
2、测试
1、相关注解
配置类注解,定义在配置类上。
设置当前Spring环境中开启注解式事务支持。
接口、类、方法注解,定义在接口、类、方法上。
为当前业务层方法添加事务(如果设置在类或接口上方则类或接口中所有方法均添加事务)。
2、事务角色
发起事务方,在Spring中通常指代业务层开启事务的方法。
加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法。
3、@Transactional常用属性
true只读事务,false读写事务,增删改要设为false,查询设为true。
设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。
当出现指定异常进行事务回滚。
4、事务传播行为
比如上述测试案例中,我们给log方法上的@Transactional设置了传播属性为REQUIRES_NEW,表示当前事务协调员会自己开启一个事务。并不会因为transfer发生回滚而回滚。
Ⅰ REQUIRED(默认);
Ⅱ SUPPORTS;
Ⅲ MANDATORY;
Ⅳ REQUIRES_NEW;
Ⅴ NOT_SUPPORTED;
Ⅵ NEVER;
Ⅶ NESTED。
以上即为Spring AOP-事务管理的全部内容,感谢阅读。
如何用java开启mysql事务,要求详细看你是什么事务,jdbc事务,还是分布式事务,还是容器事务
1,编程式事务管理(jdbc的事务是绑定在connection上的)
Connection conn = null
try
{
Class.forName("com.mysql.jdbc.Driver")
conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","password")
conn.setAutoCommit(false) //取消自动提交
PreparedStatement ps = conn.prepareCall("update something")
ResultSet rs = ps.executeQuery()
conn.commit() //手动提交
}
catch (Exception e)
{
conn.rollback()
e.printStackTrace()
}
finally
{
conn.close()
}
2,声明式事务
先在工程的application.xml配置文件中添加如下代码,开启事务
<!-- 声明式事务控制配置 -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="datasource" ref="bassDataSource"></property>
</bean>
然后在你需要开启事务的接口前面添加注解
@Transactional(rollbackFor = IOException.class)
public void add(String name) throws IOException
{
System.out.println("可以再类里和方法里面添加事务注解0~0")
throw new IOException()
}
直接调用接口方法就好
分布式事务处理(mysql貌似在5.X之后才支持) 的话,
1.可以直接使用spring+atomikos框架进行管理
参考:http://blog.chinaunix.net/uid-21162795-id-3424973.html
就不贴测试代码了,自己看着配置吧
2,使用JTA(Java Transaction API)进行分布式事务管理(测试代码如下)
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.SQLException
import javax.naming.InitialContext
import javax.sql.DataSource
import javax.transaction.SystemException
import javax.transaction.UserTransaction
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource
//分布式事务处理
public class transferAccount
{
@SuppressWarnings("null")
public void testTransferAccount()
{
UserTransaction userts = null
Connection connA = null
PreparedStatement psA = null
InitialContext context = null
Connection connB = null
PreparedStatement psB = null
try
{
//获得事务管理对象
userts = (UserTransaction) context.lookup("java:comp/UserTransaction")
//获取两个数据库
connA = getDataSourceA().getConnection()
connB = getDataSourceB().getConnection()
//开启事务
userts.begin()
//sql语句
psA = connA.prepareStatement("我加1")
psB = connB.prepareStatement("我减1")
//执行sql
psA.executeUpdate()
psB.executeUpdate()
//事务提交
userts.commit()
} catch (Exception e)
{
try
{
userts.rollback()
} catch (IllegalStateException | SecurityException
| SystemException e1)
{
e1.printStackTrace()
}
e.printStackTrace()
}
finally
{
try
{
psA.close()
psB.close()
connA.close()
connB.close()
} catch (SQLException e)
{
e.printStackTrace()
}
}
}
public DataSource getDataSourceA()
{
MysqlDataSource dataSource = new MysqlDataSource()
dataSource.setDatabaseName("mysql")
dataSource.setServerName("server")
dataSource.setPortNumber(1433)
dataSource.setUser("test")
dataSource.setPassword("test")
return dataSource
}
public DataSource getDataSourceB()
{
MysqlDataSource dataSource = new MysqlDataSource()
dataSource.setDatabaseName("mysql")
dataSource.setServerName("server")
dataSource.setPortNumber(1435)
dataSource.setUser("test1")
dataSource.setPassword("test1")
return dataSource
}
}
一般来说,应该在service层加事务,因为service层是比较底层的,它可以把一个业务 *** 作分解成多个小的 *** 作,比如:添加用户,添加订单,添加购物车等,这些 *** 作都可以在service层加事务,以保证数据的完整性。而controller层一般只是接收用户的请求,然后调用service层的接口,所以不需要加事务。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)