「java设置事物」java开启事务

博主:adminadmin 2023-01-19 06:21:09 274

本篇文章给大家谈谈java设置事物,以及java开启事务对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

java中怎样处理事物

JAva 对事务得处理主要体现在持久层,但是由于spring的出现,事务全部在服务层完成了。事务在增删改 之后才需要进行提交,但是用户使用最多的是查询,所以事务不算太频繁,同时事务的处理也是非常耗费资源的,据我所知 hhibernate 这个框架的事务处理上 是由代理对象实现的

java里,怎么写事务控制

Java中为了控制事务的一致性,会使用插入回滚点、callback方法,保证数据不被篡改,示例如下:

public String delete(String id) {

String ID = id;

 db = new getConnection();

 Connection con = db.getConnection();

 try {

con.setAutoCommit(false);

db.executeUpdate("delete from helloworld where ID=" + ID); //更新操作1

db.executeUpdate("delete from helloworld _book where ID=" + ID); //更新操作2

db.executeUpdate("delete from helloworld_user where ID=" + ID); //更新操作3

con.commit();//提交JDBC事务

con.setAutoCommit(true);

db.close();

return “success”;

 }

 catch (Exception e) {

con.rollBack();//回滚JDBC事务

e.printStackTrace();

db.close();

return “fail”;

}

}

java中的事物处理是怎么回事?

事务处理是企业应用需要解决的最主要的问题之一。J2EE通过JTA提供了完整的事务管理能力,包括多个事务性资源的管理能力。但是大部分应用都是运行在单一的事务性资源之上(一个数据库),他们并不需要全局性的事务服务。本地事务服务已然足够(比如JDBC事务管理)。

本文并不讨论应该采用何种事务处理方式,主要目的是讨论如何更为优雅地设计事务服务。仅以JDBC事务处理为例。涉及到的DAO,Factory,Proxy,Decorator等模式概念,请阅读相关资料。

也许你听说过,事务处理应该做在service层,也许你也正这样做,但是否知道为什么这样做?为什么不放在DAO层做事务处理。显而易见的原因是业务层接口的每一个方法有时候都是一个业务用例(User Case),它需要调用不同的DAO对象来完成一个业务方法。比如简单地以网上书店购书最后的确定定单为例,业务方法首先是调用BookDAO对象(一般是通过DAO工厂产生),BookDAO判断是否还有库存余量,取得该书的价格信息等,然后调用 CustomerDAO从帐户扣除相应的费用以及记录信息,然后是其他服务(通知管理员等

java ee项目中 spring托管的事务应该怎么设置隔离级别

可以在XML文件中进行配置,下面的代码是个示意代码

tx:advice id="txAdvice" transaction-manager="txManager"

    tx:attributes

      tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"/增加记录的方法

      tx:method name="get*" propagation="REQUIRED" isolation="READ_COMMITTED"/获取记录的方法

      tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED"/删除的方法

      tx:method name="update*" propagation="REQUIRED" isolation="SERIALIZABLE"/更改记录的方法

    /tx:attributes

  /tx:advice

下面扩展将一下spring里面事务的传播属性和事务隔离级别。

一、Propagation (事务的传播属性)

Propagationkey属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

1: PROPAGATION_REQUIRED

加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务

比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候,

ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA

的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。

这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被

提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚

2: PROPAGATION_SUPPORTS

如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行

3: PROPAGATION_MANDATORY

必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常

4: PROPAGATION_REQUIRES_NEW

这个就比较绕口了。 比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为PROPAGATION_REQUIRES_NEW,

那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,

他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在

两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,

如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。

5: PROPAGATION_NOT_SUPPORTED

当前不支持事务。比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,

那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而他以非事务的状态运行完,再继续ServiceA.methodA的事务。

6: PROPAGATION_NEVER

不能在事务中运行。假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER ,

那么ServiceB.methodB就要抛出异常了。

7: PROPAGATION_NESTED

理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,

而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。

而Nested事务的好处是他有一个savepoint。

*****************************************

ServiceA {

/**

* 事务属性配置为 PROPAGATION_REQUIRED

*/

void methodA() {

try {

//savepoint

ServiceB.methodB(); //PROPAGATION_NESTED 级别

} catch (SomeException) {

// 执行其他业务, 如 ServiceC.methodC();

}

}

}

********************************************

也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如

ServiceC.methodC,继续执行,来尝试完成自己的事务。

但是这个事务并没有在EJB标准中定义。

二、Spring事务的隔离级别

 1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应

 2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

 3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

 4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

 5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

什么是脏数据,脏读,不可重复读,幻觉读?

脏读: 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

            

幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

事务是什么?在java中如何手工执行事务

事务 指作为单个逻辑工作单元执行的一系列操作。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性;

在java中你要手工执行事务,如果是jdbc连接数据库,那么就设置提交的时候手动提交

conn.setAutoCommit(false);//conn 是connection对象

当结束后

conn.commit();

希望对你有帮助

java 单元测试spring的xml事物设置某个方法只读不起作用怎么回事

1,首先保证你的spring配置了该方法的事物。

2,在该事物管理的方法中有非读操作。

代码如下:

//配置文件

bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"

    property name="dataSource" ref="dataSource"/

/bean

tx:advice id="TestAdvice" transaction-manager="transactionManager"

    tx:attributes

        tx:method name="query*" propagation="REQUIRED" read-only="true"/

        !--这里对update开头的方法加上read-only 用于测试--

        tx:method name="update*" propagation="REQUIRED" read-only="true"/

    /tx:attributes

/tx:advice

aop:config 

    aop:pointcut id="transaction" expression="execution(* com.straw.spring.service.*.*(..))"/

    aop:advisor advice-ref="TestAdvice" pointcut-ref="transaction"/

/aop:config

//java service implements

package com.straw.spring.service;

import com.straw.spring.model.User;

/**

 * Created by Administrator on 2017/3/28.

 */

public interface UserService {

    User queryUserbyId(int id);

    User updateAndQueryUserbyId(int i, String hai);

}

//实现类

package com.straw.spring.service.impl;

import com.straw.spring.dao.UserDao;

import com.straw.spring.model.User;

import com.straw.spring.service.UserService;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.HashMap;

import java.util.Map;

/**

 * Created by Administrator on 2017/3/28.

 */

@Service

public class UserServiceImpl  implements UserService {

    @Resource

    UserDao userDao;

    public User queryUserbyId(int id) {

        System.out.println(1111);

        //return super.queryUserbyId(id);

        return userDao.selectByPrimaryKeyForUpdate(id);

    }

    public User updateAndQueryUserbyId(int id, String userName) {

        System.out.println(2222);

        MapString, Object params = new HashMapString, Object();

        params.put("id", id);

        params.put("userName", userName);

        //修改操作

        userDao.updateUserbyId(params);

        User user = userDao.selectByPrimaryKeyForUpdate(id);

        return user;

    }

}

//dao层

package com.straw.spring.dao;

import com.straw.spring.model.User;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.stereotype.Repository;

import java.util.Map;

public interface UserDao extends BaseRepositoryUser {

}

//基础dao

package com.straw.spring.dao;

import com.straw.spring.model.Organization;

import com.straw.spring.model.User;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.stereotype.Repository;

import java.io.Serializable;

import java.util.Map;

/**

 * Created by Administrator on 2017/3/28.

 */

public interface  BaseRepositoryM extends Serializable {

    public void save(M m);

    public abstract M selectByPrimaryKeyForUpdate(int id);

    public int updateUserbyId(Map params);

}

//mapper 配置文件

mapper namespace="com.straw.spring.dao.UserDao"

    resultMap id="BaseResultMap" type="com.straw.spring.model.User"

        id column="id" property="id" jdbcType="INTEGER"/

        result column="user_name" property="userName" jdbcType="VARCHAR"/

        result column="pass_word" property="passWord" jdbcType="VARCHAR"/

    /resultMap

    

    update id="updateUserbyId" parameterType="java.util.Map"

        update t_user set user_name = #{userName} where id=#{id}

    /update

    

!--主键查询--

select id="queryUserbyId" resultMap="BaseResultMap" parameterType="java.lang.Long"

    select  t_user.*

    from  t_user

    trim prefix="where" prefixOverrides="AND |OR "

        id = #{id,jdbcType=BIGINT}

    /trim

/select

!--加锁查询--

select id="selectByPrimaryKeyForUpdate" resultMap="BaseResultMap" parameterType="java.lang.Long"

    select  t_user.*

    from  t_user t_user

    trim prefix="where" prefixOverrides="AND |OR "

        id = #{id,jdbcType=BIGINT}

    /trim

    for update

/select

 /mapper   

 

 //测试类

 package com.straw;

import com.straw.spring.model.User;

import com.straw.spring.service.UserService;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Configurable;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})

@Configurable

public class TestMain  {

    @Autowired

    UserService userService;

    @Test

    public void test1(){

        User user = userService.queryUserbyId(1);

        if (user != null ){

            System.out.println(user.getUserName());

            System.out.println(user.getUserExt().getId());

        }

    }

    @Test

    public void test2(){

        User user = userService.updateAndQueryUserbyId(1,"hai");

        if (user != null ){

            System.out.println(user.getUserName());

            System.out.println(user.getUserExt().getId());

        }

    }

}

// test2 运行结果

### Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

java设置事物的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java开启事务、java设置事物的信息别忘了在本站进行查找喔。