Travas-Locks

Propaganda
Locks
Locks
• Mecanismo de sincronização entre threads.
• Muito utilizado em operações de transações.
• Transações devem ser programadas de modo
que seus efeitos sobre dados compartilhados
sejam equivalentes em série.
Transaction life histories
Successful
Aborted by client
Aborted by server
openTransaction
openTransaction
openTransaction
operation
operation
operation
operation
operation
operation
server aborts
transaction
operation
operation
closeTransaction
abortTransaction
Instructor’s Guide for Coulouris, Dollimore
and Kindberg Distributed Systems:
Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
operation ERROR
reported to client
Controle Concorrência
• Um problema bem conhecidos de transações
concorrentes no contexto do exemplo do
banco:
– “lost update”
• Como este problema pode ser evitado
usando-se equivalência serial de execuções
de transações ?
Operações
• Assuminos que cada das operações deposit,
withdraw, getBalance, setBalance, é uma
synchronized operação, isto é, seus efeitos
sobre a variável de instância que registra o
balance (saldo) de uma conta é atômico.
O problema “lost update”
• Sejam as contas A, B e C.
• Sejam duas transações T e U sobre as contas
A, B e C.
• Os valores iniciais de balance são:
– A igual a $100,
– B igual a $200,
– C igual a $300.
O problema “lost update”
• A transação T transfere um valor da conta A
para a conta B.
• A transação U transfere um valor da conta C
para a conta B.
• Em ambos os casos, o valor transferido é
calculado para aumentar o saldo (balance) de
B em 10%.
Observação da Figura
• Daqui para frente, são mostradas as
operações que afetam a variável balance
(saldo) de uma conta, nas sucessivas linhas
das seguintes figuras.
Observação da Figura
• E o leitor da figura deve assumir que uma
operação, numa linha em particular, é
executada num tempo posterior do que a
linha acima.
The “lost update” problem
Transaction
:T
Transaction
balance= b.getBalance();
b.setBalance(balance*1.1);
a.withdraw(balance/10)
balance=b.getBalance();
:U
balance= b.getBalance();
b.setBalance(balance*1.1);
c.withdraw(balance/10)
$200
b.setBalance(balance*1.1)
$220
a.withdraw(balance/10)
$80
balance= b.getBalance()
$200
b.setBalance(balance*1.1)
$220
c.withdraw(balance/10)
$280
Instructor’s Guide for Coulouris, Dollimore
and Kindberg Distributed Systems:
Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Resultado Correto!
• O efeito sobre a conta B de executar as
transações T e U, deve ser para aumentar o
balance (saldo) de B em 10%, duas vezes.
Assim, o valor final deveria ser $242.
Resultado !
• Os efeitos de permitir as transações T e U
rodarem concorrentemente como na figura
“lost update”, ambas as transações obtém o
balance de B como $200 e então deposit $20.
• O resultado é incorreto, aumentando o
balance de B em $20 ao invés de $42.
Por que ??
Erro !!!
• O “update” de U é perdido porque T
sobrescreve balance de B sem ver o “update”
de U.
• Ambas as transações tem de ler o valor inicial
de balance de B, antes de qualquer delas
escrever o novo valor de balance de B.
The “lost update” problem
• O problema de “lost update” ocorre quando
duas transações T e U lêem o valor velho de
uma variável (balance) e então usa ele para
calcular o novo valor dessa variável (balance).
The “lost update” problem
• Isto não pode acontecer, se uma transação é
realizada antes da outra, porque a última
transação lerá o valor escrito pela última
transação.
Resolvendo “lost update”
• Pode-se resolver o problema “lost update” por
meio de uma equivalência serial de
intercalações de transações T e U.
A serially equivalent interleaving of T and U
T Transaction
U Transaction
balance = b.getBalance()
b.setBalance(balance*1.1)
a.withdraw(balance/10)
balance = b.getBalance()
b.setBalance(balance*1.1)
c.withdraw(balance/10)
balance = b.getBalance()
$200
b.setBalance(balance*1.1)
$220
a.withdraw(balance/10)
balance = b.getBalance()
$220
b.setBalance(balance*1.1)
$242
c.withdraw(balance/10)
$278
$80
Instructor’s Guide for Coulouris, Dollimore
and Kindberg Distributed Systems:
Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
A serially equivalent interleaving of T and U
• A figura anterior mostra uma intercalação na
qual as operações que afetam uma conta
compartilhada, B, são realmente seriais.
• Ou seja, a transação T faz todas as suas
operações sobre B, antes da transação U fazer.
A serially equivalent interleaving of T and U
• Uma outra intercalação de T e U que tem esta
propriedade é uma na qual a transação U
completa suas operações sobre a conta B,
antes da transação T iniciar.
Locks
• Um servidor pode obter equivalência em série
das transações, dispondo em série o acesso
aos objetos.
Equivalência em Série
• A figura seguinte mostra um exemplo de como
a equivalência serial pode ser obtida com
certo grau de concorrência.
• As transações T e U acessam a conta B, mas T
conclui seu acesso antes que U comece a
acessá-la.
A serially equivalent interleaving of T and U
T Transaction
U Transaction
balance = b.getBalance()
b.setBalance(balance*1.1)
a.withdraw(balance/10)
balance = b.getBalance()
b.setBalance(balance*1.1)
c.withdraw(balance/10)
balance = b.getBalance()
$200
b.setBalance(balance*1.1)
$220
a.withdraw(balance/10)
balance = b.getBalance()
$220
b.setBalance(balance*1.1)
$242
c.withdraw(balance/10)
$278
$80
Instructor’s Guide for Coulouris, Dollimore
and Kindberg Distributed Systems:
Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Equivalência Serial
• Como implementar no computador ???
• Usa-se, para controle de concorrência, o
mecanismo de Locks.
Locks (Travas)
• Um exemplo simples de mecanismo para a
disposição das tranasações em série, é o uso
de locks (travas) exclusivos.
• Nesse esquema, o servidor tenta impedir o
acesso (travar) a qualquer objeto que esteja
para ser usado por qualquer operação da
transação de um cliente.
Locks
• Se um cliente solicitar o acesso a um objeto
que já está travado devido a transação de
outro cliente, o pedido será suspenso e o
cliente querendo acessar, deverá esperar até
que o objeto seja destravado.
• A próxima figura mostra o uso de locks (travas)
exclusivos.
Transactions T and U with exclusive locks
Transaction : T
balance = b.getBalance()
b.setBalance(bal*1.1)
a.withdraw(bal/10)
Transaction : U
Operations
Operations
Locks
openTransaction
bal = b.getBalance()
closeTransaction
Locks
lock B
openTransaction
b.setBalance(bal*1.1)
a.withdraw(bal/10)
balance = b.getBalance()
b.setBalance(bal*1.1)
c.withdraw(bal/10)
lock A
bal = b.getBalance()
waits for T ’s
lock on B
unlock A , B
lock B
b.setBalance(bal*1.1)
c.withdraw(bal/10) lock C
closeTransaction
Instructor’s Guide for Coulouris, Dollimore and Kindberg
Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
unlock B C
,
Locks em Java
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
...
// Criação de um objeto acessLock da classe Lock para
// controlar a sincronização de algum objeto
// compartilhado.
Private Lock acessLock = new ReentrantLock;
Locks em Java
// Condições para controlar a leitura e a escrita.
private Condition podeEscrever = acessLock.newCondition();
private Condition podeLer = acessLock.newCondition();
...
// Escreve valor no objeto compartilhado ...
// Para travar o objeto compartilhado, quando o método
// set() for chamado ...
public void set( ... ) {
accessLock.lock();
// chama o método lock e bloqueia (trava) o
objeto compartilhado. Esse método
esperará até que a trava esteja
disponível.
...
// Se o objeto estiver sem condição de escrita ...
podeEscrever.await(); // Espera uma condição ocorrer
...
Locks em Java
// Sinaliza a thread que está esperando para fazer uma
leitura.
podeLer.signal(); // avisa que uma condição ocorreu ...
...
finally
{
accessLock.unlock; // destrava o objeto compartilhado.
}
} // fim do método set.
Locks em Java
// Ler valor no objeto compartilhado ...
// Para travar o objeto compartilhado, quando o método
// get() for chamado.
public void get() {
accessLock.lock()
// chama o método lock e bloqueia (trava) o
objeto compartilhado. Esse método
esperará até que a trava esteja
disponível.
...
// Se o objeto estiver sem condição de ser lido...
podeLer.await(); // Espera uma condição ocorrer
...
Locks em Java
// Sinaliza a thread que está esperando para fazer uma
// leitura.
podeEscrever.signal(); // avisa que uma condição ocorreu
...
finally
{
accessLock.unlock; // destrava o objeto compartilhado.
}
} // fim do método get.
Locks em Java
• Execute os exemplos Deitel 23.11 e 23.12,
aproveitando os códigos em 23.6 (interface
Buffer), 23.7 (Producer) e 23.8 (Consumer),
para o Relacionamento Producer-Consumer
com sincronização usando Locks.
Download