<html>
<head>
<title>Contas bancarias</title>
</head>
<?php
include 'db.inc';
include 'error.inc';
/* executa um comando sql */
function db_execute($sql)
{
global $db;
return pg_query($db,$sql);
}
/* lista todas as contas */
function db_lista_contas()
{
$sql = "SELECT * FROM conta ORDER BY numero";
$result = db_execute($sql);
$nrows = pg_numrows($result);
printf("<pre>\n");
printf("<b>numero nome saldo</b>\n");
for($i=0; $i<$nrows; $i++)
{
$tuple = pg_fetch_array($result,$i);
printf("%s %10s %10s\n",
$tuple['numero'], $tuple['nome'], $tuple['saldo']);
}
printf("</pre>\n");
}
/* retorna o saldo da conta $numconta */
function db_saldo( $numconta )
{
$sql = "SELECT saldo FROM conta WHERE numero=$numconta";
$result = db_execute($sql);
return pg_result($result,0,0);
}
/* retorna o saldo da conta $numconta e faz um 'lock' à linha */
function db_saldo_for_update( $numconta )
{
$sql = "SELECT saldo FROM conta WHERE numero=$numconta FOR UPDATE";
$result = db_execute($sql);
return pg_result($result,0,0);
}
/* retorna true se $numconta existe. retorna false caso contrário */
function db_existe_conta( $numconta )
{
$sql = "SELECT saldo FROM conta WHERE numero=$numconta";
$result = db_execute($sql);
$nrows = pg_numrows($result);
if( $nrows < 1 )
return false;
else
return true;
}
/* transfere $quantidade da $conta1 para $conta2.
retorna true se a operação tiver sucesso.
retorna false caso contrario.
*/
function db_transfere($conta1,$conta2,$quantidade)
{
/* começa a transacção */
db_execute("BEGIN WORK");
/* verifica se existe dinheiro suficiente na conta 1 */
$saldo = db_saldo_for_update($conta1);
if( $saldo >= $quantidade ) {
/* transfere o dinheiro */
db_execute("UPDATE conta SET saldo=saldo+$quantidade
WHERE numero=$conta2");
sleep(5); // so para poder testar a concorrencia...
db_execute("UPDATE conta SET saldo=saldo-$quantidade
WHERE numero=$conta1");
db_execute("COMMIT WORK");
return true;
}
else {
db_execute("ROLLBACK WORK");
return false;
}
}
?>
<h1>Tabela 'conta'</h1>
<?php
$db = dbconnect($connection_string);
$numConta1 = $_POST["numConta1"];
$numConta2 = $_POST["numConta2"];
$quantidade = $_POST["quantidade"];
if( isset($numConta1) && isset($numConta2) && isset($quantidade)) {
// verifica que $quantidade nao e' negativo
if($quantidade<0)
printf("<p>ERRO: quantidade negativa!</p>\n");
// verifica que as contas existem
if(!db_existe_conta($numConta1))
printf("<p>ERRO: Conta $numConta1 nao existe!</p>\n");
if(!db_existe_conta($numConta2))
printf("<p>ERRO: Conta $numConta2 nao existe!</p>\n");
// efectua a transaccao
if( db_transfere($numConta1,$numConta2,$quantidade) )
printf("<p>Foi transferido %d da conta %d para a conta %d</p>\n",
$quantidade, $numConta1, $numConta2);
else
printf("<p>Saldo insuficiente na conta $numConta1!</p>\n");
}
db_lista_contas();
?>
<hr>
<h1>Transferencia de dinheiro</h1>
<form action="<?php echo $PHP_SELF; ?>" method="post">
<table border=0>
<tr>
<td align=right>Numero da conta 1:</td>
<td align=left><input type="text" name="numConta1" size="15"></td>
</tr>
<tr>
<td align=right>Numero da conta 2:</td>
<td align=left><input type="text" name="numConta2" size="15"></td>
</tr>
<tr>
<td align=right>Quantidade:</td>
<td align=left><input type="text" name="quantidade" size="15"></td>
</tr>
<tr>
<td align=left><input type="submit" value="transferir"></td>
</tr>
</table>
</form>
<?php
pg_close($db);
?>
</body>
</html>