Programmatic Transactions (Java)

programmatic transaction
start :

Spring can support both programmatic and declarative transactions. The most primitive transaction management method provided by
Spring is based on TransactionDefinition, PlatformTransactionManager, TransactionStatus programmatic transactions. The programmatic transaction management of TransactionTemplate
is the encapsulation of the original transaction management method using the template method design pattern.

Why use programmatic transactions?

A programmatic transaction is a transaction processing method used in database operations, by writing a program to control the commit or rollback of the transaction. Compared with declarative transactions, programmatic transactions need to manually specify operations such as transaction start, commit, and rollback, and have more fine-grained control capabilities.

Here are some advantages of using programmatic transactions:

Flexibility: Programmatic transactions can be flexibly controlled and processed according to the complexity of business logic and data operations, ensuring data consistency and integrity;

Readability: Programmatic transaction code can directly display the boundary and execution sequence of the transaction, which is convenient for understanding and debugging;

Security: Using programmatic transactions can prevent problems such as database deadlocks and data conflicts, and ensure data security and reliability in multiple concurrent accesses;

Cross-framework support: Programmatic transactions can be used across frameworks without relying on any specific framework or container, allowing developers to freely choose their own tools for development and deployment;

Incremental modification: When using programmatic transactions, you can control the size and scope of each transaction, so it is useful when the requirements of large-scale systems change frequently, and it is more convenient to add or modify some functions of the system without will affect the entire system.

Of course, the use of programmatic transactions also has some disadvantages, such as lengthy code and poor maintainability. It is necessary to weigh the pros and cons when using it and choose the best transaction processing method according to business needs.

Individuals choose it because of business needs, for example:

// 原代码
@Transactional(rollbackFor = Exception.class)
public Boolean alterOperation(Object obj){
    
    
// 查询操作1
object1 = service.select();
// 数据处理
.......
// 查询操作2
object2 = service.select2();
// 查询操作3
object3 = service.select3();
.....
// 此处省略查询操作与逻辑......

// 最后增删改操作.....
boolean rs = update();
}

We can see that the above method uses annotations to open the transaction, and it is a relatively long transaction. The whole method does a lot of logical operations such as queries. If the query is complex, the long query time will aggravate the impact on system resources and performance. .So try to shorten the transaction execution time here, so that other queries can get resources and locks faster. What
we can do now is:

Split long transactions : We should split a long process into multiple short transactions as much as possible to ensure that each transaction only focuses on the data and logic it needs, and avoid locking unnecessary other resources in the transaction;

Reduce transaction isolation level : Lowering the isolation level from the highest level (such as Serializable) to a lower level (such as Read Committed) can reduce the number and scope of locks and improve concurrency performance, but it may also cause data consistency problems. Need to assess risks to make decisions;

Use optimistic lock : When updating records, we can use optimistic lock technology, that is, read the record first and save information such as its version number or timestamp in variables, and then check whether the record has been updated by other transactions when modifying. If not, perform an update operation. This way can avoid using pessimistic locks to occupy too many resources

Reasonably design the database architecture : Reasonable table design and index design can reduce the granularity of locks, and enabling partition tables or sharding can also prevent data from being queried across multiple nodes.


The following uses programmatic transactions to split long transactions

Basic use: reduce transaction granularity and prevent queries from blocking for a long time.

# 引用注入 事务模板
@Autowired
private TransactionTemplate transactionTemplate;

# 在需要添加事务方法里编写代码
public Boolean test(){
    
    
    // 各种查询代码
    // 开启事务
    Boolean rs = transactionTemplate.execute(transactionStatus -> {
    
    
        return Boolean.TRUE; 或者 return Boolean.FALSE;
    }
}

So when we use TransactionTemplate.execute( ... ) to perform transaction management, there are two options for the incoming parameters:
1. TransactionCallback
2.

The difference between TransactionCallbackWithoutResult is quite obvious from the naming, one has a return value, and the other is No return value. This choice depends on whether you are reading or writing.

Example:
Perform transaction management with the help of (TransactionCallback), both with a return value:

public Object getObject(String str) {
    
    
        /*
         *  执行带有返回值<Object>的事务管理
         */
        transactionTemplate.execute(new TransactionCallback<Object>() {
    
    
            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {
    
    
                try {
    
    
                      ...
                    //.......   业务代码
                    return new Object();
                } catch (Exception e) {
    
    
                    //回滚
                    transactionStatus.setRollbackOnly();
                    return null;
                }
            }
        });
}

Execute transaction management with (TransactionCallbackWithoutResult), neither return value:

public void update(String str) {
    
    

         /*
         *  执行无返回值的事务管理
         */
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
    
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
    
    

                try {
    
    

                    // ....  业务代码
                } catch (Exception e){
    
    
                    //回滚
                    transactionStatus.setRollbackOnly();
                }

            }
        });
}

Guess you like

Origin blog.csdn.net/AKALXH/article/details/130170484