28 tháng 12, 2017
30 tháng 11, 2017
Tìm kiếm với Git
28 tháng 9, 2017
2 tháng 9, 2017
26 tháng 8, 2017
26 tháng 7, 2017
Quản lý transaction trong Spring Framework - Spring @Transaction
Spring là một framework Java được sử dụng phổ biến nhất hiện nay, nó mang đến rất nhiều tính năng và nhiều phần bổ trợ cho các ứng dụng Java. Tuy nhiên, hầu hết mọi người đều có khuynh hướng sử dụng những tính năng này mà không thực sự hiểu cơ chế bên dưới của chúng.
1. Cách sử dụng và trường hợp sử dụng
@Transaction(value = "myTransactionManager", propagation = Propagation.REQUIRED) public void myMethod() { ... }
Thuộc tính value
của annotation @Transaction
không bắt buộc phải được khai báo. Nếu không khai báo thuộc tính này thì mặc định Spring sẽ tìm kiếm một bean
bất kì được khai báo bên trong context
có tên là "transactionManager" (đây là convention mặc định trong Spring).
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
2. Cấu hình sử dụng transaction trong Spring context
Muốn annotation @Transaction
có thể hoạt động được, ta sẽ phải khai báo thẻ <tx:annotation-driven>
(trong đó tx
là rút gọn của namespace "http://www.springframework.org/schema/tx" hoặc cũng có thể tạm hiểu đây là một alias cho namespace này).
3. Phân tích code
3.1. Khai báo spring bean
Ở phần này, chúng ta sẽ xem xét cách mà Spring context
xử lý khi khai báo sử dụng thẻ <tx:annotation-driven>
1, org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser
/**
* Parses the '<code></code>' tag. Will
* {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
* with the container as necessary.
*/
public BeanDefinition parse(Element element, ParserContext parserContext) {
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj"
registerTransactionAspect(element, parserContext);
} else {
// mode="proxy"
// DEFAULT MODE
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
Hầu hết, chúng ta sẽ đều đi vào block else
của block điều kiện if-else
trong đoạn code bên trên (mode="proxy"), vì vậy chúng ta sẽ gọi AopAutoProxyConfigurer.configureAutoProxyCreator()
22 tháng 7, 2017
26 tháng 6, 2017
Đánh chỉ mục hiệu quả khi sử dụng PostgreSQL
Hệ quản trị cơ sở dữ liệu PostgreSQL có nhiều loại chỉ mục - index
khác nhau, cũng như các cách sử dụng chỉ mục khác nhau. Qua bài viết này, tôi muốn đưa ra một góc nhìn tổng quan về các loại chỉ mục hiện tại đang được PostgreSQL hỗ trợ, và giải thích cách sử dụng khác nhau của loại chỉ mục phổ biến nhất - B-Tree
.
Sử dụng chỉ mục là một cách hiệu quả để truy xuất số lượng tương đối nhỏ các bản ghi từ bảng dữ liệu. Nó sẽ chỉ hữu ích khi số lượng các bản ghi được truy vấn ra từ một bảng không quá lớn (ví dụ, truy vấn bản ghi theo điều kiện - mệnh đề WHERE
). Chỉ mục B-Tree
sẽ rất hữu ích khi ta muốn tránh phải sắp xếp lại các bản ghi đã được lựa chọn.
1. Các loại chỉ mục:
Postgres hỗ trợ các loại chỉ mục sau:
B-Tree
: Hầu như, tất cả các cơ sở dữ liệu hiện nay đều hỗ trợ loại chỉ mụcB-Tree
, và trong hệ quản trị cơ sở dữ liệu PostgreSQL thìB-Tree
là chỉ mục mặc định nếu như thực hiện câu lệnh truy vấn tạo chỉ mục mặc địnhCREATE INDEX
. ChữB
trongB-Tree
là viết tắt của từ Balanced - nghĩa là cân bằng, và ý tưởng của thuật toán là số lượng dữ liệu trên cả nhánh của cây dữ liệu sẽ tương đối bằng nhau. Do đó, số lần phải thực hiện tìm bản ghi ở hai bên luôn luôn giống nhau. Các câu truy vấn bằng hay truy vấn phạm vi sẽ rất hiệu quả nếu kết hợp sử dụng cùng với chỉ mụcB-Tree
, chúng hoạt động với tất cả các kiểu dữ liệu và cả giá trịNULL
. Loại chỉ mụcB-Tree
được thiết kế để có thể làm việc tốt với cơ chế cache, thậm chí ngay cả khi chỉ cache một phần của dữ liệu.Hash
: Chỉ mụcHash
chỉ hữu ích khi truy vấn so sánh bằng, nhưng có thể bạn sẽ không bao giờ sử dụng đến loại chỉ mục này vì nó không an toàn, bạn sẽ cần phải tự đánh lại chỉ mục nếu như có lỗi xảy ra nhưng các đối tượng liên quan sẽ không được thông báo về sự thay đổi này, vì vậy ưu điểm của loại chỉ mụcHash
so với loại chỉ mụcB-Tree
là không đáng kể.
28 tháng 5, 2017
PostgreSQL Concurrency và MVCC
Một trong những điểm hấp dẫn nhất của hệ quản trị cơ sở dữ liệu Postgres đó là cách mà nó thực hiện điều khiển tương tranh giữa các transaction, nghĩa là read
sẽ không bao giờ chặn write
và ngược lại. Nói một cách dễ hình dung hơn, nếu hai transaction thực thi cùng một lúc thì nguyên tắc thực thi là thực thi độc lập, Postgres thực hiện được điều này là nhờ một cơ chế gọi là Multi Version Concurrency Control (MVCC)
. Kĩ thuật này không phải chỉ riêng Postgres mới có, mà đã có nhiều hệ quản trị cơ sở dữ liệu khác cũng đang thực hiện các cách tương tự với MVCC
để điều khiển tương tranh giữa các transaction bao gồm: Oracle, Berkeley DB, CouchDB và các hệ quản trị cơ sở dữ liệu khác nữa. Việc hiểu cách MVCC
được triển khai như thế nào trong PostgreSQL rất quan trọng, vì điều này giúp các nhà phát triển phần mềm có thể thiết kế các ứng dụng có tính đồng thời cao mà có sử dụng đến PostgreSQL, hoặc phần nào giúp giải quyết được rất nhiều vấn đề khó có thể gặp phải trong tương lai.
MVCC hoạt động như thế nào?
Mỗi một transaction trong PostgreSQL đều có một transaction id
- id này là một số nguyên 32-bit, gọi là XID
. Các transaction này bao gồm các câu lệnh đơn như INSERT
, UPDATE
hoặc DELETE
, và một nhóm các câu lệnh tạo thành một khối lệnh được đặt bên trong hai từ khóa BEGIN
- COMMIT
. Khi bắt đầu một transaction, Postgres tạo ra một XID
và gán nó cho transaction hiện tại. Ta có thể nhìn thấy được XID
của transaction hiện tại bằng cách gọi hàm txid_current()
có sẵn trong PostgreSQL.
SELECT CAST(txid_current() AS TEXT);Postgres lưu tất cả thông tin của một transaction vào bên trong
table data
của hệ thống, những thông tin này sẽ được Postgres dùng để xác định một bản ghi sẽ có trạng thái ẩn hay hiện đối với một transaction.
Một điều thú vị nữa trong cơ chế MVCC
này của Postgres đó là ngoài các column
đã được khai báo trong quá trình tạo bảng thì mỗi bản ghi của một bảng sẽ có thêm hai cột bổ sung:
xmin
- xác địnhXID
của transaction đãinsert
bản ghi nàyxmax
- xác địnhXID
của transaction đãdelete
bản ghi này
Nếu ta không truy vấn tới hai cột này, mặc định chúng sẽ bị ẩn đi. Ta có thể truy vấn giá trị của hai cột này như các cột bình thường khác có trong một bảng.