Spring itself does not have transactions, Spring transactions are on the basis of database transactions to encapsulate and expand, Spring supports declarative transactions, programing transactions two, this article mainly for declarative transactions to explain, this article for “Turing College” course notes
There are no more than the following steps when we use transactions
- Access to the database Connection Connection con = DriverManager. GetConnection ()
- Con.setautocommit (true/false);
- Performing data Operations (CRUD)
- Rollback con.mit ()/con.rollback()
- Close the connection conn.close()
In fact, Spring is in the framework for us to do open, commit/rollback operations, so that business code and transaction operations decoupled. How does Spring automatically add transaction operations before and after the specified method? This is where dynamic proxies come in
The proxy pattern
-
Problem solved: Decoupling the secondary business from the primary business. , secondary business: play a supporting role to assist the smooth implementation of the main business, often exist in a large number of projects
Specific examples are as follows:
interface
public interface UserDao {
void save(a);
}
Copy the code
Interface implementation, target object
public class UserDaoImpl implements UserDao {
@Override
public void save(a) {
System.out.println("Data has been saved"); }}Copy the code
Proxy objects
public class ProxyFactory {
private Object target;
public ProxyFactory(Object object) {
this.target = object;
}
public Object getProxyObject(a){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),new InvocationHandler(){
/ * * *@paramProxy is responsible for listening to objects *@paramMethod Specifies the intercepted business method@paramArgs The argument to the intercepted business method *@return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before do something...");
Object returnValue= method.invoke(target,args);
System.out.println("after do something...");
returnreturnValue; }}); }}Copy the code
The test method
public static void main(String[] args) {
// The target object
UserDao target = new UserDaoImpl();
// Create proxy objects for the target object
UserDao proxy = (UserDao) new ProxyFactory(target).getProxyObject();
proxy.save();
}
Copy the code
The output
Combined with the proxy mode, the implementation principle of Spring transaction is easy to understand. Business logic is the main business, and the transactions that need to be reused are the secondary business. Spring transaction is to add opening, commit and rollback operations before and after the business code through dynamic proxy to realize transaction operations
Spring transaction features are as follows
- Support for isolation levels for legacy data transactions
- Added the concept of transaction propagation to provide the ability to merge or isolate multiple transactions
- Declarative transactions are provided to separate business code from transactions and make transactions easy to use
Propagation of Spring transactions
attribute | Attribute values | describe |
---|---|---|
Support the present | PROPAGATION_REQUIRED | If there is no current thing, create a new thing, if there is already a thing, add to the thing. This is the most common choice. |
PROPAGATION_SUPPORTS | Supports the current thing, and if there is no current thing, executes as a non-thing. | |
PROPAGATION_MANDATORY | Use the current thing and throw an exception if there is no current thing. | |
The current thing is not supported | PROPAGATION_REQUIRES_NEW (isolated) | Create a new thing, and hang the current thing if it exists. |
PROPAGATION_NOT_SUPPORTED | Performs operations in a non-transactional manner, suspending the current thing if it exists. | |
PROPAGATION_NEVER(force non-thing) | Execute as a non-transaction, throwing an exception if a transaction currently exists. | |
Set of things | PROPAGATION_NESTED | If a thing currently exists, it is executed within a nested thing. If there is no current thing, something similar to PROPAGATION_REQUIRED is performed. |
Spring transaction isolation level
Isolation level | Dirty Read | NonRepeatable Read | Phantom Read |
---|---|---|---|
Read uncommitted | may | may | may |
Read committed | Can’t be | may | may |
Repeatable read (Repeatable read) | Can’t be | Can’t be | may |
SERIALIZABLE | Can’t be | Can’t be | Can’t be |
Dirty read:
One thing reads an uncommitted update from another thing
Unrepeatable read:
In the same thing, multiple reads of the same data will return different results, in other words, subsequent reads can read the updated data already committed by another thing. In contrast, “repeatable reads” guarantee that the same data is read multiple times in the same thing, i.e. subsequent reads cannot read the updated data that has been committed by another thing.
Phantom reads:
Query a table if the data does not exist, insert a, concurrent time, but found that there are two identical data. This is the problem of illusion reading.
Spring provides three interfaces to use transactions:
-
TransactionDefinition TransactionDefinition
-
PlatformTransactionManager transaction management
-
TransactionStatus Transaction runtime status
The original address
Cbaj. Gitee. IO/blog / 2020/0…