精华内容
下载资源
问答
  • 面试问点:关于spring事务顺序执行

    千次阅读 2019-05-14 09:26:24
    面试官问你:spring定义两个事务顺序执行该如何操作? 在有的项目或者业务场景会有一个应用内切换多个数据源的场景。这个时候其实就关系到了事务的优先顺序问题。这里变回有要求切换数据源的aop事务要在数据库或者...

    面试官问你:spring定义两个事务顺序执行该如何操作?

    在有的项目或者业务场景会有一个应用内切换多个数据源的场景。这个时候其实就关系到了事务的优先顺序问题。这里变回有要求切换数据源的aop事务要在数据库或者涉及数据库操作的事务之前。
    这里就涉及到一个spring的关键词:order。
    定义事务的顺序可以用order进行解决。
    order越小,则越优先执行。默认值为200。

    <!-- 定义事务 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <aop:config expose-proxy="true" proxy-target-class="true">
        <aop:pointcut id="pc" expression="execution(* com.owe.test.server.biz.service.*.*(..))"/>
        <aop:advisor pointcut-ref="pc" advice-ref="dataSourceAspect" order="1"/>
    </aop:config>
    

    转一个帖子,有关于order的定义和解释:
    https://www.cnblogs.com/zjrodger/p/5635933.html

    展开全文
  • A需要调B,B有事物,B需要调C,C也有事物 求问:是同时运行两事物还是一
  • SpringBoot数据源事务管理

    千次阅读 2018-06-28 11:48:40
    采用SpringBoot进行后端开发,项目里面配置了多台Mysql数据库,需要涉及场景为新增或修改数据时需要同时写入多台数据库,并保证事务一致,即要么所有数据库都写入成功入库,要么都写入...当项目中存在多个数据源时...

    采用SpringBoot进行后端开发,项目里面配置了多台Mysql数据库,需要涉及场景为新增或修改数据时需要同时写入多台数据库,并保证事务一致,即要么所有数据库都写入成功入库,要么都写入失败回滚;

    我们知道,Spring提供了事务管理,有声明式事务和编程式事务,声明式事务我们可以直接用@transactional注解作用于需要事务支持的方法上即可,该注解属性有:

     

    当项目中存在多个数据源时,我们可以通过@Transactional(name="xxxTransactionManager")来指定使用的事务管理器,其实就是使用哪个数据源嘛,但是如果被注解的方法需要同时支持两个事务管理器呢,这个时候如果用@Transactional注解就不合适了,属性name只支持字符串类型,所以只能填一个,如果不传name属性,而且项目没有配置默认的事务管理器,在调用方法时则会抛出未指定默认事务管理器的异常。

    这个时候,我们可以用编程式事务来解决这个问题。

    首先,事务管理器还是需要配置的。比如我下面就配置了两个Mysql的数据源和事务管理器

    import javax.sql.DataSource;
    
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.PlatformTransactionManager;
    
    @Configuration
    public class DataSourceConfig {
    
    	// A库datasource
    	@Bean
    	@Primary
    	@ConfigurationProperties(prefix = "spring.datasource.primary")
    	public DataSource primaryDataSource() {
    		return DataSourceBuilder.create().build();
    	}
    
    	// B库datasource
    	@Bean(name = "secondaryDataSource")
    	@Qualifier("secondaryDataSource")
    	@ConfigurationProperties(prefix = "spring.datasource.secondary")
    	public DataSource secondaryDataSource() {
    		return DataSourceBuilder.create().build();
    	}
    
    	// A库JdbcTemplate
    	@Bean(name = "primaryJdbcTemplate")
    	@Primary
    	public JdbcTemplate primaryJdbcTemplate(DataSource dataSource) {
    		return new JdbcTemplate(dataSource);
    	}
    
    	// B库JdbcTemplate
    	@Bean(name="secondaryJdbcTemplate")
    	public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryJdbcTemplate") DataSource dataSource){
    		return new JdbcTemplate(dataSource);
    	}
    	
    	// A库事务管理器
    	@Bean
    	@Qualifier("primaryTransaction")
    	public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
    	    return new DataSourceTransactionManager(primaryDataSource);
    	}
    
    	// B库事务管理器
    	@Bean
    	@Qualifier("secondaryTransaction")
    	public PlatformTransactionManager secondaryManager(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
    	    return new DataSourceTransactionManager(secondaryDataSource);
    	}
    }
    
     

    配置了事务管理器,那怎么使用呢?

    我们可以写一个注解,作用其实和Spring提供的@Transactional一样,只是这个注解接收多个不同是事务管理,然后将这个注解作用到对应的Service方法上。

    自定义的注解

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    /**
     * 自定义事务注解
     * value为String类型数组,传入为定义的事务管理器
     * @author 一iTa
     *
     */
    @Retention(RetentionPolicy.RUNTIME)  
    @Target({ElementType.METHOD,ElementType.PARAMETER})  
    public @interface CustomTransaction {  
        String[] value() default {};  
    }  

    作用到方法上

    @CustomTransaction(value = {"primaryTransaction","secondaryTransaction"})
    public void insertLine(List<Line> lines){
        log.info("xxx pre");
        // 各种操作....
        xxxDao.insertLine(lines);
        log.info("xxx post");
        return result;
    }

    ok,注解现在作用到具体的方法上了,但是现在还是不能生效的,我们需要在Aop里面去通过编程式事务使之生效。

    用的是SpringBoot,所以采用注解的方式实现Aop还是比较容易的。

    import java.util.Stack;
    
    import org.apache.commons.lang.ArrayUtils;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.support.DefaultTransactionDefinition;
    
    @Aspect
    @Configuration
    public class TransactionAop {
    
    	final Logger logger = LogManager.getLogger(TransactionAop.class);
    
    	
    	@Pointcut("@annotation(com.only.annotation.CustomTransaction)")
    	public void CustomTransaction() {
    	}
    
    
    	@Pointcut("execution(* com.only.custom.controller.*.**(..))")
    	public void excudeController() {
    	}
    
    
    	@Around(value = "CustomTransaction()&&excudeController()&&@annotation(annotation)")
    	public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, CustomTransaction annotation) throws Throwable {
    		Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack = new Stack<DataSourceTransactionManager>();
    		Stack<TransactionStatus> transactionStatuStack = new Stack<TransactionStatus>();
    
    		try {
    
    			if (!openTransaction(dataSourceTransactionManagerStack, transactionStatuStack, annotation)) {
    				return null;
    			}
    
    			Object ret = thisJoinPoint.proceed();
    
    			commit(dataSourceTransactionManagerStack, transactionStatuStack);
    
    			return ret;
    		} catch (Throwable e) {
    
    			rollback(dataSourceTransactionManagerStack, transactionStatuStack);
    
    			logger.error(String.format("MultiTransactionalAspect, method:%s-%s occors error:",
    					thisJoinPoint.getTarget().getClass().getSimpleName(), thisJoinPoint.getSignature().getName()), e);
    			throw e;
    		}
    	}
    
    	/**
    	 * 开启事务处理方法
    	 * 
    	 * @param dataSourceTransactionManagerStack
    	 * @param transactionStatuStack
    	 * @param multiTransactional
    	 * @return
    	 */
    	private boolean openTransaction(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
    			Stack<TransactionStatus> transactionStatuStack, CustomTransaction multiTransactional) {
    
    		String[] transactionMangerNames = multiTransactional.value();
    		if (ArrayUtils.isEmpty(multiTransactional.value())) {
    			return false;
    		}
    
    		for (String beanName : transactionMangerNames) {
    			DataSourceTransactionManager dataSourceTransactionManager = (DataSourceTransactionManager) SpringUtil
    					.getBean(beanName);
    			TransactionStatus transactionStatus = dataSourceTransactionManager
    					.getTransaction(new DefaultTransactionDefinition());
    			transactionStatuStack.push(transactionStatus);
    			dataSourceTransactionManagerStack.push(dataSourceTransactionManager);
    		}
    		return true;
    	}
    
    	/**
    	 * 提交处理方法
    	 * 
    	 * @param dataSourceTransactionManagerStack
    	 * @param transactionStatuStack
    	 */
    	private void commit(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
    			Stack<TransactionStatus> transactionStatuStack) {
    		while (!dataSourceTransactionManagerStack.isEmpty()) {
    			dataSourceTransactionManagerStack.pop().commit(transactionStatuStack.pop());
    		}
    	}
    
    	/**
    	 * 回滚处理方法
    	 * 
    	 * @param dataSourceTransactionManagerStack
    	 * @param transactionStatuStack
    	 */
    	private void rollback(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
    			Stack<TransactionStatus> transactionStatuStack) {
    		while (!dataSourceTransactionManagerStack.isEmpty()) {
    			dataSourceTransactionManagerStack.pop().rollback(transactionStatuStack.pop());
    		}
    	}
    }

    1. 首先根据指定的多个TransactionManager依次开启事务,这个次序不影响,因为其实大家都是平等的

    2. 其次就是调用目标方法执行具体的业务逻辑

    3. 若是成功返回则提交每个事务,若中途报错,那么就回滚每个事务

    这里用了Stack来保存TransactionManager和TransactionStatus主要是为了保证顺序一致,当然也可以使用其他容器类。

    到此,整个Aop就配置好了,启动工程,当调用insertLine方法时,事务将由aop的openTransaction方法开启并往下执行。

     

     

     

    展开全文
  • 因为可能存在多个事务同时存取同一数据的情况。 12、数据库锁有哪些分类? 共享锁:多个事务可查看,不能修改 排它锁:只有一个事务封锁,其他不能进入,只能等待X锁释放才能访问。 更新锁:用来锁定修改的...

    成长之路,一起走!总结一些知识,方面自己学习,也方面热爱学习的伙伴们可以更好的成长!
    项目直接是静态的Html,下载后可以直接访问!
    地址:https://github.com/dufyun/kuyu/tree/master/kuyuTechHtml

    1、JAVA中有哪些锁的关键字,请分别描述下各自的特点?
    http://www.tuicool.com/articles/NnQjyq
    http://blog.csdn.net/smcwwh/article/details/7193666

    1)Sychronized 同步,并发锁
        可以加在方法和代码块上,但是要注意区分 “static”
        (2)java.util.concurrent.locks下的锁实现同步 
            a:可重入的锁ReentrantLock
                使用Lock的时候,lock与unlock一定要配对。
            b:可重入的读写锁ReentrantReadWriteLock
                没有writer,读取锁可以由对个reader线程同时保持,而写入锁定是独占的。

    2、synchronized有哪些用法,请举例说明?

    可以对方法和代码代码块进行同步,用法对类或者对象上锁。同步!

    3、什么是死锁,死锁发生的条件有哪些,请用文字以及图解说明?

        至少两个线程等待对方持有的锁,无限的循环下去!

    4、死锁如何避免,可用代码举例说明?

    1)主要原因是嵌套封锁的使用!2)无限等待对方持有的锁,让等待时间有个上限。
    (3)设计代码的时候,程序每次只能获取一个锁。

    5、活锁和饥饿如何理解,可用文字及图解说明?

        活锁和锁么有太大关系,是一种形象的比喻。
        饥饿:一个线程因为cpu时间被被其他线程全部抢走而得不到cpu运行时间

    6、多线程中专门用于处理线程锁的是哪个子包?

    java.util.concurrent

    7、多线程中如何保证锁对象可以被解锁

     finally unlock(); 其他的没有想到!

    8、多线程中专门用于处理线程锁的子包与synchronized关键字最大的区别是什么?

        synchronized是关键字,线程锁的子包是类。是的类换,就可以更灵活地使用锁的特性!可以被继承等

    9、多线程中的锁,应该位于哪个层面?

    业务代码层面,service
    锁:分对象锁和类锁。 常见的mvc模型中 dao层基本上是不用你去管锁的问题的。数据库基本帮你搞定了。 
    倒是可以对某些service加一些必要的锁保证业务调用的的一致性。 这是我的理解。

    10、两个线程执行的代码片段要实现同步互斥的效果,有什么要求?
    java多线程与线程并发二:线程互斥:http://www.cnblogs.com/bailiyi/p/3619983.html

        代码片段一次只能被一个线程使用,互斥的线程必须使用同一个对象上锁!
        同步是一种更为复杂的互斥,而互斥是一种特殊的同步。
    
      也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,
      另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!
    
      总结:
    
      互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。
      但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
    
      同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。
      在大多数情况下,同步已经实现了互斥。

    11、数据库锁的概念是什么?

    对数据库中数据对象进行加锁,防止并发或者多用户操作破坏数据库数据的不一致性。
    因为可能存在多个事务同时存取同一数据的情况。

    12、数据库锁有哪些分类?

    共享锁:多个事务可查看,不能修改
    排它锁:只有一个事务封锁,其他不能进入,只能等待X锁释放才能访问。
    更新锁:用来锁定修改的资源。防止共享锁导致的死锁现在!
    共享锁修改数据两步:获得共享锁,升级为排它锁,在修改数据。
    

    13、数据库锁的粒度体现在哪些方面,各自有什么特点?

    小-行:增大并发量,开销也大,维护锁多
    大-表:降低并发量,开销低,维护锁少!

    14、事务的概念是什么,有哪些基本属性?

    数据库管理系统 - 逻辑单位-有限的操作序列!
    ACID属性:
    Atomicity : 原子性
    Consistency:一致性
    Isolation:隔离线
    Durability:持久性

    15、事务有哪几种隔离级别,请从弱到强分别类举说明?

    1:Read Uncommitted(读未提交):一个事务可以读取另一个未提交事务的数据。
    2:Read Committed(读提交):一个事务要等另一个事务提交后才能读取数据。可以update
    3:Repeatable Read(重复读):在开始读取数据(事务开启)时,不再允许修改操作。不可以update,可以insert
    4:Serializable(序列化):Serializable 是最高的事务隔离级别,在该级别下,
    事务串行化顺序执行,可以避免脏读、不可重复读与幻读。

    16、在事务的并发操作中,可能出现的情况是哪些?

    脏读,不可重复读,幻读

    17、大多数数据库默认的事务隔离级别是哪个?MySql的是否一样,如果不一样请指出?

    MySql: Repeatable Read
    其他的Sqlservice,oracle : read committed 

    18、结合Spring谈谈你对事务传播性的理解(文字和图解都可以)?

        在ssh开发中,我们一般将事务设置在Service层,当调用service一个方法进行数据库的操作时候
    能够保持我们使用的操作在一个事务中。
        如果在本service层中除了调用了Dao层方法,还调用其他类的service层方法,
    此时必须要保证调用的Service层的方法和我本身的方法在同一事务中,否则不能保证事务的一致性。
    此时就出现了事务的传播问题。Spring大多数情况使用 PROPGATION_REQUIRED:如果存在一个事务,
    则支持当前事务,没有事务则开启新的事务。

    19、Spring的事务控制有哪两个主要特性,请分别简单说明?

    传播级别和数据隔离级别!
    传播级别定义的是事务的控制范围,事务隔离级别定义的是事务在数据库读写方面的控制范围。

    20、Spring的事务框架设计理念的基本原则是什么?它有哪些事务管理方式,请分别说明下?

    理念:让事务管理的关注点与数据访问的关注点相互分离。
    方式:
    (1)编程式事务
    (2)声明式事务


    如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
    祝你今天开心愉快!


    欢迎访问我的csdn博客,我们一同成长!

    不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

    博客首页http://blog.csdn.net/u010648555

    展开全文
  • Spring中实现数据源事务管理

    万次阅读 热门讨论 2015-07-25 20:26:43
    Spring中实现多数据源事务管理前言由于项目中引入了多个数据源,并且需要对多个数据源进行写操作,那么多数据源的事务管理自然成了不可避免的问题,这也让我对@Transactional注解有了进一步的理解(但实际上也并不是...

    Spring中实现多数据源事务管理

    前言

    由于项目中引入了多个数据源,并且需要对多个数据源进行写操作,那么多数据源的事务管理自然成了不可避免的问题,这也让我对@Transactional注解有了进一步的理解(但实际上也并不是非常深入)

    然而这是一个演进的过程,刚开始项目中并没有使用@Transactional指定具体的TransactionManager,所以新增一个数据源后,对原有的事务产生了影响了,这也是偶尔在一次测试报错而结果没有回滚之后才发现的,遂对于@Transactional注解的一些参数项进行了了解。

    研究

    由于容器中存在两个TransactionManager,那么被@Transactional注解的方法到底使用了哪个TransactionManager来进行事务管理,抑或是同时使用了两个TransactionManager来进行事务管理都是我们需要搞清楚的问题。
    首先我们先看看@Transactional注解上有没有提供配置项来指定TransactionManager,果不其然,发现value属性就是用来指定具体TransactionManager的,通过id或者name来指定唯一一个TransactionManager,那么对于只需要一个事务管理的方法,问题就简单多了:

        @Transactional(value = "database2TransactionManager")
        public void test(String a) {
            // business operation
        }

    关于不指定TransactionManager时会使用哪一个TransactionManager,有兴趣的童鞋可以参考另一篇文章,讲的比较清晰:http://blog.sina.com.cn/s/blog_8f61307b0100ynfb.html

    好了,回到我们研究的问题,那么对于需要写入多个数据源的业务方法该怎么办呢?

    进一步研究

    看来@Transactional是没有提供这种功能了,那么就自己写了一个吧。我记得Spring中的事务管理分编程式事务和声明式事务。我们平时使用的@Transactional就是声明式事务,它的好处其实也就是灵活度更高、代码的耦合性更低,最终的事务管理实现还是一样的,只不过将具体逻辑都剥离到了切面中。所以我们可以手写一个切面来写一次“编程式事务”,当然在具体应用时,还是声明式的。

    Java中一般编程式事务的写法:

    public class UserServiceImpl implements UserService {
        @Resource
        private TransactionManager txManager;
        @Resource
        private UserDao userDao;
        @Resource
        private AddressDao addressDao;
    
        public boolean saveUser(User user) {
            TransactionDefinition txDefinition = new TransactionDefinition();
            TransactionStatus txStatus = txManager.getTransaction(txDefinition);
            boolean result = false;
            try {
                result = userDao.save(user);
                if(!result){
                    return false;
                }
                result = addressDao.save(user.getId(), user.getAddress());
                txManager.commit(txStatus);
            } catch (Exception e) {
                result = false;
                txManager.rollback(txStatus);
            }
            return result;
        }
    }

    我们借用这个逻辑将事务管理相关提取到切面中,并在进入目标方法之前,让多个TransactionManager都开启事务,并在成功执行后一并提交或失败后一并回滚,具体代码:

    /**
     * @author Zhu
     * @date 2015-7-15
     * @version 0.0.1
     * @description
     */
    public class MultiTransactionalAspect {
    
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        public Object around(ProceedingJoinPoint pjp,
                MultiTransactional multiTransactional) throws Throwable {
    
            Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack = new Stack<DataSourceTransactionManager>();
            Stack<TransactionStatus> transactionStatuStack = new Stack<TransactionStatus>();
    
            try {
    
                if (!openTransaction(dataSourceTransactionManagerStack,
                        transactionStatuStack, multiTransactional)) {
                    return null;
                }
    
                Object ret = pjp.proceed();
    
                commit(dataSourceTransactionManagerStack, transactionStatuStack);
    
                return ret;
            } catch (Throwable e) {
    
                rollback(dataSourceTransactionManagerStack, transactionStatuStack);
    
                logger.error(String.format(
                        "MultiTransactionalAspect, method:%s-%s occors error:", pjp
                                .getTarget().getClass().getSimpleName(), pjp
                                .getSignature().getName()), e);
                throw e;
            }
        }
    
        /**
         * @author Zhu
         * @date 2015-7-25下午7:55:46
         * @description
         * @param dataSourceTransactionManagerStack
         * @param transactionStatuStack
         * @param values
         */
        private boolean openTransaction(
                Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
                Stack<TransactionStatus> transactionStatuStack,
                MultiTransactional multiTransactional) {
    
            String[] transactionMangerNames = multiTransactional.values();
            if (ArrayUtils.isEmpty(multiTransactional.values())) {
                return false;
            }
    
            for (String beanName : transactionMangerNames) {
                DataSourceTransactionManager dataSourceTransactionManager = (DataSourceTransactionManager) ContextHolder
                        .getBean(beanName);
                TransactionStatus transactionStatus = dataSourceTransactionManager
                        .getTransaction(new DefaultTransactionDefinition());
                transactionStatuStack.push(transactionStatus);
                dataSourceTransactionManagerStack
                        .push(dataSourceTransactionManager);
            }
            return true;
        }
    
        /**
         * @author Zhu
         * @date 2015-7-25下午7:56:39
         * @description
         * @param dataSourceTransactionManagerStack
         * @param transactionStatuStack
         */
        private void commit(
                Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
                Stack<TransactionStatus> transactionStatuStack) {
            while (!dataSourceTransactionManagerStack.isEmpty()) {
                dataSourceTransactionManagerStack.pop().commit(
                        transactionStatuStack.pop());
            }
        }
    
        /**
         * @author Zhu
         * @date 2015-7-25下午7:56:42
         * @description
         * @param dataSourceTransactionManagerStack
         * @param transactionStatuStack
         */
        private void rollback(
                Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
                Stack<TransactionStatus> transactionStatuStack) {
            while (!dataSourceTransactionManagerStack.isEmpty()) {
                dataSourceTransactionManagerStack.pop().rollback(
                        transactionStatuStack.pop());
            }
        }

    整体结构很清晰:
    1. 首先根据指定的多个TransactionManager依次开启事务,这个次序不影响,因为其实大家都是平等的。
    2. 其次就是调用目标方法执行具体的业务逻辑
    3. 若是成功返回则提交每个事务,若中途报错,那么就回滚每个事务

    其中为什么要用Stack来保存TransactionManagerTransactionStatus呢?那是因为Spring的事务处理是按照LIFO/stack behavior的方式进行的。如若顺序有误,则会报错:

    java.lang.IllegalStateException: Cannot deactivate transaction synchronization - not active
            at org.springframework.transaction.support.TransactionSynchronizationManager.clearSynchronization(TransactionSynchronizationManager.java:313)
            at org.springframework.transaction.support.TransactionSynchronizationManager.clear(TransactionSynchronizationManager.java:451)
            at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:986)
            at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:782)
            at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactio

    题外话

    刚开始碰到这个问题的时候,先想到的是分布式事务管理,也去看了JTA相关的文章,但是好像比较麻烦,而且都是一些老文章,于是想试试自己实现,最后也实现了。所以想知道JTA TransactionManager究竟有什么用呢?

    展开全文
  • SQL事务

    万次阅读 多人点赞 2019-09-11 10:30:12
    锁:用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写。 死锁:是数据库性能的重量级杀手之一,而死锁却是不同事务之间抢占数据资源造成...
  • MySQL事务

    千次阅读 2021-02-23 17:19:17
    什么是事务? 在执行SQL语句的时候,...I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离; D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。 事务隔离级
  • 也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务...
  • (一般一个程序中包含多个事务) 2.事务的开始和结束可以由用户显式控制,如果用户没有显式地定义事务,则由数据库管理系统按默认规定自动划分事务。在SQL中,定义事务的语句一般有三条: BEGIN TRANS...
  • SQLServer中的事务与锁

    2021-03-03 23:39:07
    在一个事务中,你写啦2条sql语句,一条是修改订单表状态,一条是修改库存表库存-1。如果在修改订单表状态的时候出错,事务能够回滚,数据将恢复到没修改之前的数据状态,下面的修改库存也就不执行,这样确保
  • 事务与锁

    千次阅读 2016-06-26 00:24:50
    锁:用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写。 死锁:是数据库性能的重量级杀手之一,而死锁却是不同事务之间抢占数据资源...
  • 事务隔离级别 1. READ UNCOMMITTED : RU 称为浏览访问,可以读取事务未提交的数据。 2. READ COMMITTED : RC 称为游标稳定,只能读取已经提交事务的数据。...当一个事务开始未提交时,其他事务均不能执行
  • 不同事务之间可能会互相影响,比如一个事务修改另一个事务也改了,但是另一个事务的修改把这个事务的修改给覆盖掉了,这就是所说的事务并发控制问题。 如果不对事务进行并发控制,可能会产生四种异常情况 幻读...
  • 数据库是一个共享资源,为了充分利用数据库资源,发挥数据库共享资源的特点,应该允许多个用户并行地存取数据库。但这样就会产生多个用户程序并发存取同一数据的情况,为了避免破坏一致性,所以必须提供并发控制机制...
  • 用户系统中事务的并发执行意味着事务存在同一数据资源的可能性,即可能会发生数据冲突,并产生一系列意想不到的错误。但是事务可以并发执行的确可以加快整个系统的执行效率,因此有必要对事务的并发执行做出控制...
  • 延续上篇博文一文读懂Spring事务和MySQL事务与锁我们继续学习。 通常数据库事务是并发执行的(如果你的数据库隔离级别非serializable)),但是...多个事务的读写操作按时间排序的执行序列: T1:r1(A)w1(A)r1(B)w1(B)...
  • MySQL explain执行计划解读

    万次阅读 多人点赞 2014-03-02 21:22:51
    本文我们主要介绍了MySQL性能分析以及explain的使用,包括:组合索引、慢查询分析、MYISAM和INNODB的锁定、MYSQL的事务配置项等,希望能够对您有所帮助。 1.使用explain语句去查看分析结果 如explain select * from...
  • Spring事务管理

    千次阅读 2016-03-27 16:11:00
    Spring事务的传播行为和隔离级别
  • 从一错误谈谈事务管理

    千次阅读 2012-03-27 11:43:55
    最近在产品中发现了一错误,和分布式事务相关,仔细梳理了一下,还发现不少值得深究的东西,下面就分享给大家。 错误堆栈信息比较长,只摘出关键的一段: [2/28/12 0:57:28:195 MST] 00000016 SystemErr R ...
  • 数据库 -- 事务管理

    千次阅读 2019-04-29 11:31:01
    活动的(active):初始状态,事务执行时处于这状态 部分提交的(partially committed): 最后一条语句执行后。 (此时虽然事务已经完全执行,但是由于实际输出可能仍驻留在主存中,因此一硬件故障可能阻止其...
  • 解惑 spring 嵌套事务

    千次阅读 2016-10-06 11:24:41
    原文链接在所有使用 spring 的应用中, 声明式事务管理可能是使用率最高的功能了, 但是绝大多数人并不能深刻理解事务声明中不同事务传播属性配置的的含义, 让我们来看一下 TransactionDefinition 接口中的定义 /** ...
  • 程序员必知的 89 操作系统核心概念

    万次阅读 多人点赞 2020-03-31 19:13:39
    操作系统需要处理管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一让用户与系统交互的操作界面。 shell:它是一程序,可从键盘获取...
  • 数据库事务管理原理

    千次阅读 2016-04-06 15:15:13
    数据库是一个共享资源,可以提供多个用户使用。这些用户程序可以一个一个地串行执行,每个时刻只有一个用户程序运行,执行对数据库的存取,其他用户程序必须等到这个用户程序结束以后方能对数据库存取。但是如果一个...
  • 事务可串行化原理

    千次阅读 2019-05-23 23:12:26
    访问并可能更新各种数据项的一程序执行单元。通常由高级数据库操作语言或编程语言通过 JDBC 或 ODBC 嵌入式数据库...Atomicity:原子性,事务是一不可分割的工作单位,事务中包括的操作要么都执行,要么都不执行...
  • 事务的ACID

    2010-05-27 20:10:00
    也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始...
  • SQL SERVER 事务和锁

    2019-01-07 17:51:32
    锁:用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写。 先举一典型的业务 A给B转账100元 在数据库中 实际进行了两步操作 A的账户...
  • 事务的并发:在某一时间段内,多个事务同时存取相同的数据库数据。 并发操作时由于不能隔离而产生的问题: 丢失修改:t4时间后,事务A对数据D的修改可能丢失。 读入“脏”数据:由于发生错误导致事务回退,...
  • spring 嵌套事务

    千次阅读 2018-06-12 20:29:00
    1.嵌套事务,主要是serviceA methodA,调用serviceB methodB的这种情况,method AB均声明了事务的情况。 2.上述外事务调用内事务,异常出现不同位置(外内),以及加上try catch时,数据回滚的具体结果,详细见下面...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,700
精华内容 9,880
关键字:

多个事务执行的次序