Declarative Transaction Management স্প্রিং ফ্রেমওয়ার্কে একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা ট্রানজেকশন ব্যবস্থাপনার জন্য কোডের মধ্যে কোনো সরাসরি লজিক না লিখে শুধুমাত্র কনফিগারেশন ব্যবহার করে ট্রানজেকশন পরিচালনা করতে সহায়তা করে। স্প্রিংে AOP (Aspect-Oriented Programming) ব্যবহার করে আপনি Declarative Transaction Management খুব সহজে এবং কার্যকরভাবে পরিচালনা করতে পারেন।
স্প্রিং এওপির মাধ্যমে ট্রানজেকশন ব্যবস্থাপনা
স্প্রিং এওপি (Spring AOP) ডিক্লেয়ারেটিভ ট্রানজেকশন ম্যানেজমেন্ট সরবরাহ করে। আপনি @Transactional অ্যানোটেশন ব্যবহার করে কোনো মেথডের চারপাশে ট্রানজেকশন পরিচালনা করতে পারেন, এবং এই কার্যকলাপ স্প্রিং এওপি ব্যবহার করে ঘটবে। স্প্রিং এওপি অ্যাডভাইজ ব্যবহার করে, আপনি Before, After, এবং AfterReturning অ্যাডভাইজগুলি দিয়ে ট্রানজেকশন পরিচালনা করতে পারবেন।
স্প্রিং ট্রানজেকশন ম্যানেজমেন্ট কনফিগারেশন সাধারণত দুইভাবে করা হয়:
- Declarative Transaction Management: অ্যানোটেশন বা XML কনফিগারেশনের মাধ্যমে।
- Programmatic Transaction Management: কোডের মাধ্যমে ট্রানজেকশন পরিচালনা করা।
এখানে আমরা Declarative Transaction Management ব্যবহারের জন্য AOP কিভাবে ব্যবহার করা যায় তা বিস্তারিতভাবে আলোচনা করব।
Declarative Transaction Management with AOP
স্প্রিং AOP ব্যবহার করে Declarative Transaction Management করতে, সাধারণত @Transactional অ্যানোটেশন ব্যবহার করা হয়। যখন আপনি @Transactional অ্যানোটেশন ব্যবহার করেন, তখন স্প্রিং এওপি TransactionInterceptor (একটি AOP অ্যাডভাইজ) অ্যাপ্লিকেশনের মেথডে স্বয়ংক্রিয়ভাবে ট্রানজেকশন কার্যকর করে।
স্প্রিং এওপি ব্যবহার করে Transactional Management করার মূল সুবিধা হল যে, আপনি ম্যানুয়ালি কোনো ট্রানজেকশন কোড লেখার পরিবর্তে শুধুমাত্র @Transactional অ্যানোটেশন দিয়ে ব্যাবহারকারীর মেথডের চারপাশে ট্রানজেকশন পরিচালনা করতে পারবেন।
1. স্প্রিং এওপি দিয়ে Declarative Transaction Management কনফিগারেশন
স্প্রিং ফ্রেমওয়ার্কে ট্রানজেকশন ম্যানেজমেন্টের জন্য প্রথমে স্প্রিং কনফিগারেশন ফাইলটি সঠিকভাবে কনফিগার করা প্রয়োজন।
Step 1: স্প্রিং কনফিগারেশন
স্প্রিং কনফিগারেশন ফাইলে DataSource, Transaction Manager, এবং EnableTransactionManagement সঠিকভাবে কনফিগার করতে হয়।
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;
@Configuration
@EnableTransactionManagement
public class AppConfig {
// DataSource Bean
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("password");
return dataSource;
}
// TransactionManager Bean
@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager();
}
}
এখানে:
- @EnableTransactionManagement: স্প্রিং ট্রানজেকশন ম্যানেজমেন্ট সক্ষম করে, যা
@Transactionalঅ্যানোটেশনকে কাজ করতে দেয়। - DataSource Bean: ডেটাবেসের জন্য
DataSourceকনফিগার করা হয়। - PlatformTransactionManager: ট্রানজেকশন ম্যানেজারের জন্য বিহেভিয়ার কনফিগার করা হয়।
Step 2: Service Layer Method with @Transactional
স্প্রিং এওপি ব্যবহার করে ট্রানজেকশন পরিচালনা করার জন্য @Transactional অ্যানোটেশন ব্যবহার করা হয়। যখন কোনো মেথডে @Transactional ব্যবহৃত হয়, স্প্রিং এওপি এই মেথডের চারপাশে একটি ট্রানজেকশন পরিচালনা করে।
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Transactional
public void createUser(String name, String email) {
// Code for creating user in database
System.out.println("User " + name + " created with email " + email);
// Imagine some logic that may throw an exception here
if (name == null || email == null) {
throw new RuntimeException("Invalid input parameters");
}
}
}
এখানে, @Transactional অ্যানোটেশন দিয়ে ট্রানজেকশন ম্যানেজমেন্ট করা হয়েছে। যদি কোনো RuntimeException বা ত্রুটি ঘটে, তবে ট্রানজেকশন রোলব্যাক হবে এবং পুরো মেথড কার্যকরী হবে না।
Step 3: Controller Class
এখন, আমরা একটি Controller তৈরি করব যা UserService মেথডটি কল করবে। এতে @Transactional কার্যকর হবে, এবং ব্যাচের মেথডে ট্রানজেকশন পরিচালিত হবে।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/createUser")
public String createUser(@RequestParam String name, @RequestParam String email) {
userService.createUser(name, email);
return "User created successfully";
}
}
এখন, যদি createUser মেথডে কোনো ত্রুটি ঘটে, তাহলে ট্রানজেকশন রোলব্যাক হবে এবং ডেটাবেসে কোনো পরিবর্তন হবে না।
2. ট্রানজেকশন কনফিগারেশন এবং AOP Advice
স্প্রিং এওপি TransactionInterceptor ব্যবহার করে ট্রানজেকশন ম্যানেজমেন্ট পরিচালনা করে, যখন @Transactional অ্যানোটেশন ব্যবহার করা হয়। স্প্রিং এওপি সাধারণত Before, After এবং AfterReturning অ্যাডভাইজ ব্যবহার করে, যা ট্রানজেকশন শুরুর আগে, পরে বা সফলভাবে শেষ হলে কার্যকর হয়।
TransactionInterceptor Configuration
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AopConfig {
@Bean
public ProxyFactoryBean transactionProxy() {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(userService); // userService being the target service
proxyFactoryBean.setInterceptorNames("transactionInterceptor"); // TransactionInterceptor
return proxyFactoryBean;
}
@Bean
public TransactionInterceptor transactionInterceptor() {
return new TransactionInterceptor(transactionManager(), new Properties());
}
}
এখানে, TransactionInterceptor ট্রানজেকশন পরিচালনা করার জন্য ব্যবহার করা হয় এবং ProxyFactoryBean দিয়ে সেটি মেথডে প্রয়োগ করা হয়।
সারাংশ
স্প্রিং এওপি (Spring AOP) দিয়ে Declarative Transaction Management খুবই কার্যকরভাবে পরিচালিত হতে পারে। @Transactional অ্যানোটেশন ব্যবহার করে আপনি সহজেই ট্রানজেকশন পরিচালনা করতে পারেন, এবং স্প্রিং এওপি তার পিছনে TransactionInterceptor ব্যবহার করে এসব কার্যকর করে।
এই কৌশলটি বিশেষভাবে লেনদেন সংক্রান্ত কার্যক্রমের জন্য ব্যবহার করা হয়, যেখানে ডেটা টেম্পোরারি পরিবর্তন, একাধিক মেথডের মধ্যে নির্ভরতা, এবং সফল/ব্যর্থ অবস্থায় রোলব্যাক করতে হবে।
স্প্রিং এওপি এবং ট্রানজেকশন ম্যানেজমেন্টের সাহায্যে, আপনার অ্যাপ্লিকেশনটি আরও সুসংগঠিত, নির্ভরযোগ্য এবং রক্ষণাবেক্ষণযোগ্য হয়ে ওঠে।